2010-02-24 48 views
11

我有一个连接两个表的查询。一个表具有varchar类型的列,另一个表具有数字类型。我在3个oracle数据库上执行了我的查询,并且看到我希望可以解释的一些奇怪结果。在两个数据库中,像下面这样的作品。Oracle编号和varchar加入

select a.col1, b.somecol 
from tableA a inner join tableB b on b.col2=a.col1; 

在此查询中,tableA.col1的类型为number,tableB.col2的类型为varchar。这在两个数据库中工作正常,但不在第三个。在第三个我得到(ORA-01722)错误。第三,我需要做的是这样......

select a.col1, b.somecol 
from tableA a inner join tableB b on b.col2=to_char(a.col1); 

这适用于所有数据库。我有这个问题是为什么?以上是一个简化的查询,真正的查询稍微复杂一点,可以检索大量数据,因此第一个版本要快得多。如果我能在所有环境中工作,那将会很棒。

有谁知道为什么这可能在某些oracle数据库中工作,而没有其他人没有在数据类型上强制转换?是否有能够实现此类行为的全局设置?

+1

整理将是我的第一个猜测。 Oracle通常允许隐式转换,所以它可能是一列不通过隐式转换... – 2010-02-24 23:28:09

+1

您编写了所有这些单词,但您仍然无法准确解释* how *第一个查询在第三数据库。 – APC 2010-02-24 23:42:57

+0

对不起,我在第一个查询中得到一个ORA-01722错误,第三个数据库 – broschb 2010-02-25 00:56:48

回答

15

隐式转换失败的一个原因是,连接varchar列包含的数据不是数字。甲骨文处理数为VARCHAR2加入通过将字符串(看看加里在他的评论中引用),因此它实际上执行这样的:

select a.col1, b.somecol 
from tableA a inner join tableB b on to_number(b.col2)=a.col1; 

如果tableB.col2包含哪些不是数值 - 似乎很可能,它是一个字符串毕竟 - 然后它会投掷ORA-01722: invalid number。通过将数字列显式转换为字符串,可以缩短Oracle的默认行为。

事实上,在前两个环境中没有遇到这个问题是一个运气不配置的问题。它可能随时出现,因为它只需要一个非数字字符串来打破查询。所以你真的应该在所有环境中进行明确的转换。

至于性能,你可以建立一个基于函数的索引...

create index whatever_idx on tableA (to_char(col1)) 
/
+2

稍后http://download.oracle.com/docs/cd/B19306_01/server.102/b14200 /sql_elements002.htm#r16c1-t41 “将字符值与数字值进行比较时,Oracle会将字符数据转换为数字值。” – 2010-02-25 01:07:35

+0

您可以将tableA中的数字转换为字符串,以便在tableB中存在非数字字符串时不会出错。即CAST(a.col1 AS VARCHAR(20)) – 2013-09-11 14:04:02