Performance Oracle编号和varchar连接

Performance Oracle编号和varchar连接,performance,oracle,join,to-char,ora-01722,Performance,Oracle,Join,To Char,Ora 01722,我有一个连接两个表的查询。一个表的列类型为varchar,另一个表的列类型为number。我已经在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。这在其中两个数

我有一个连接两个表的查询。一个表的列类型为varchar,另一个表的列类型为number。我已经在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数据库中有效,而在没有数据类型强制转换的其他数据库中无效吗?是否存在启用此类行为的全局设置?

隐式转换失败的一个原因是当联接varchar列包含非数字数据时。Oracle通过转换字符串(查看Gary在其评论中的引用)来处理数字到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) )
/ 

整理是我的第一个猜测。Oracle通常允许隐式转换,因此可能有一列无法通过隐式转换…您编写了所有这些单词,但仍然无法准确解释第一个查询在第三个数据库中如何不工作。抱歉,我在第一个查询中,在第三个数据库中,在稍后的第三个数据库中,出现了ORA-01722错误“在将字符值与数值进行比较时,Oracle会将字符数据转换为数值。”您可以将tableA中的数字转换为字符串,以便在tableB中存在非数字字符串时不会出错。ie cast(a.col1作为VARCHAR(20))