15

我有一个连接两个表的查询。一个表具有 varchar 类型的列,而另一个表具有数字类型。我已经在 3 个 oracle 数据库上执行了查询,并且看到了一些奇怪的结果,希望可以得到解释。在其中两个数据库上,如下所示。

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 数据库中有效,而在其他没有数据类型的情况下则无效?是否存在启用此类行为的全局设置?

4

1 回答 1

22

隐式转换失败的一个原因是当连接的 varchar 列包含非数字数据时。Oracle 通过转换字符串来处理数字到 varchar2 连接(查看 Gary 在他的评论中的引用),所以它实际上执行了这个:

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) )
/ 
于 2010-02-24T23:38:29.173 回答