比较字符串与数字oracle时的数字无效

时间:2014-09-07 15:03:26

标签: sql oracle oracle11g

你好我现在参与了一个运行超过2年的项目,昨天,我们开始面临以下问题:

一个始终使用并且每天至少运行20.000的查询,昨天没有任何内容开始返回无效的数字错误。

ORA-01722:无效号码

select orq.rt_id, orec.* from orderrec orec
  join order_header oh on (oh.order_code = orec.ordernumber and oh.page = orec.pagenumber)
  left join order_request orq on oh.orq_id = orq.orq_id
       where ordernumber=? and pagenumber=? and state < 100

问题部分是: oh.order_code = orec.ordernumber

  • order_code是一个字符串
  • ordernumber是一个数字

因为这会对客户端产生产生很大的影响,所以我将等同的比较更改为类似于查询的查询。在此更改过程开始再次运行之后没有问题。

select orq.rt_id, orec.* from orderrec orec join order_header oh on (oh.order_code like orec.ordernumber and oh.page = orec.pagenumber) left join order_request orq on oh.orq_id = orq.orq_id 
  where ordernumber=? and pagenumber=? and state < 10

此查询是与java程序一起使用的XML文件。

我怀疑为什么会发生这种情况?

1 个答案:

答案 0 :(得分:1)

我会检查ORDER_CODE字段,你说它是一个字符串,是否包含任何带有非数字字符(0-9)的新值,因为这是我对原因的猜测。

即使您的ORDER_CODE字段是字符串,当您使用数字字段加入该字段时,Oracle也会尝试将该字符串转换为数字(隐式)。您也可以在ORDER_CODE字段上使用to_number()函数,因为这是它实际处理的方式。

例如,此查询:

select *
  from tablea a
  join tableb b
    on a.order_code = b.ordernumber

如果ORDER_CODE包含仅包含数字(0-9)且没有字母的值,则不会返回错误。

但是,如果它确实包含至少一个这样的值,那么就会出现你所描述的错误。

确实可以使用LIKE来避免错误,但是它无法匹配ORDER_CODE包含字母的行。请注意,在此示例中,http://sqlfiddle.com/#!4/f00f91/1/0'9A'与9不匹配,而'8'与8匹配。

简而言之,答案是因为你加入了两个不同格式的字段,一个是字符串,一个是数字,所以隐含了从字符串到数字的转换。显然,当字符串包含诸如A,B,C等字母时,它将无法进行转换,因此它会给你错误。

你可以运行这个查询来找到“问题值”,我的猜测是最近插入的任何行都被插入,导致错误:

<强>小提琴: http://sqlfiddle.com/#!4/f5b55/1/0

select *
from order_header
where regexp_like(order_code, '[^0-9]')