【问题标题】:Oracle number and varchar joinoracle number 和 varchar join
【发布时间】:2010-02-25 17:58:25
【问题描述】:

我有一个连接两个表的查询。一个表具有 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 数据库中有效,而在其他没有数据类型的情况下则无效?是否有启用此类行为的全局设置?

【问题讨论】:

  • 整理是我的第一个猜测。 Oracle通常允许隐式转换,所以可能是一列没有通过隐式转换...
  • 你写了所有这些话,但你仍然没有设法准确地解释如何第一个查询在第三个数据库中不起作用。
  • 对不起,我在第一个查询,第三个数据库中收到 ORA-01722 错误

标签: performance oracle join to-char ora-01722


【解决方案1】:

隐式转换失败的一个原因是连接的 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) )
/ 

【讨论】:

  • download.oracle.com/docs/cd/B19306_01/server.102/b14200/… 后面一点“当比较字符值与数值时,Oracle 将字符数据转换为数值。”
  • 您可以将tableA中的数字转换为字符串,这样如果tableB中有非数字字符串,您就不会出错。即 CAST(a.col1 AS VARCHAR(20))
猜你喜欢
  • 2018-04-23
  • 1970-01-01
  • 2013-06-09
  • 2017-02-16
  • 2015-03-28
  • 2012-09-29
  • 2016-03-23
  • 2017-03-24
  • 1970-01-01
相关资源
最近更新 更多