你好我现在参与了一个运行超过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
因为这会对客户端产生产生很大的影响,所以我将等同的比较更改为类似于查询的查询。在此更改过程开始再次运行之后没有问题。
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文件。
我怀疑为什么会发生这种情况?
答案 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]')