【问题标题】:Select string as number on Oracle在Oracle上选择字符串作为数字
【发布时间】:2012-04-11 01:31:51
【问题描述】:

我发现了这种奇怪的行为,我为此伤透了脑筋……有人有什么想法吗?

Oracle 10g: 我有两个不同的表,都有这个名为“TESTCOL”的列作为Varchar2(10),不能为空。

如果我在 table1 上执行此查询,我会得到正确的结果:

select * from table1 where TESTCOL = 1234;

注意,我特别没有放置“1234”...这不是错字,这是一个动态生成的查询,我会尽量不更改它(至少在不久的将来不会)。

但是,如果我在 table2 上运行相同的查询,我会收到以下错误消息:

ORA-01722: Invalid number

两个查询都在同一个会话、同一个数据库上运行。

我一直按该列连接这两个表,并且连接工作正常,唯一的问题是每当我尝试使用该条件时。

关于一张桌子与另一张桌子有什么不同有什么想法吗?

提前致谢。

【问题讨论】:

    标签: sql oracle oracle10g


    【解决方案1】:

    如果TESTCOL 包含非数字,则Oracle 在将TESTCOL 条目转换为数字时可能会遇到问题。因为,它在内部做的是这样的:

    select * from table1 where TO_NUMBER(TESTCOL) = 1234;
    

    如果您非常确定 1234 不能表示为 VARCHAR 文字,请改用此方法,以便比较 varchar 值,而不是数字值:

    select * from table1 where TESTCOL = TO_CHAR(1234);
    

    【讨论】:

      【解决方案2】:

      您在这里遇到了隐式类型转换的危险。

      使用表达式testcol = 1234,您声明要将testcol 视为数字列,因此Oracle 尝试将该列中的所有值转换为数字。

      出现 ORA-01722 是因为该列中显然至少有一个值不是数字。

      即使你声称这是“不是一个错字”,它确实是一个。这是一个语法错误。

      您必须使用单引号将参数声明为字符串文字:where testcol = '1234'

      创建正确的条件是解决问题的唯一方法。

      【讨论】:

        【解决方案3】:

        很明显,TABLE2.TESTCOL 包含不是数字的值。将字符串与数字文字进行比较会生成隐式转换。所以 TESTCOL 中任何不能转换为数字的值都会抛出 ORA-1722。

        在比较两个表的位置并不会影响您,因为您是在比较字符串。

        所以你有几个选择,你都不喜欢。最明显的答案是清理数据,使 TABLE2 hdoesn 不包含非数字。理想情况下,您应该将此与将列更改为数字数据类型相结合。否则,您可以更改生成器,使其生成可以针对不完善的数据模型运行的代码。在这种情况下,这意味着如果映射列具有字符数据类型,则将文字用引号括起来。

        【讨论】:

          【解决方案4】:

          以下应该有效。只需替换“你的位置”即可。

          select * 
          from table1 
          where (select TO_NUMBER(TESTCOL) 
                 from table2 
                 where "your where") = 1234;
          

          【讨论】:

            猜你喜欢
            • 2020-05-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-01-28
            • 2020-02-14
            • 2018-03-14
            • 2014-09-22
            • 1970-01-01
            相关资源
            最近更新 更多