2014-09-07 4 views
0

Здравствуйте я в настоящее время участвует в проекте, который работает в течение более 2 лет, и вчера, мы начали сталкиваться следующий вопрос:Неверный номер, сравнивая строку с номером оракула

один запрос, который всегда использовался и выбежала на менее 20.000 каждый день, вчера fom ничего не начал возвращать неверную ошибку числа.

ОР-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 

Этот запрос является файлом XML, используемым с программой java.

Я сомневаюсь, почему это произошло?

+0

" order_code - это строка ". Неизменяемый закон приложений баз данных: если мы определим столбцы чисел как строку, в конце концов она будет содержать нечисловые символы. – APC

ответ

1

Я бы уточнил, есть ли поле ORDER_CODE, которое вы называете строкой, содержит любые новые значения с нецифровыми символами (0-9), так как это было бы моим предположением относительно причины.

Даже если поле ORDER_CODE является строкой, когда вы присоединяетесь к этому полю с полем числа, Oracle попытается преобразовать эту строку в число (неявно). Вы также можете использовать функцию to_number() в поле ORDER_CODE, потому что именно так она обрабатывается.

Например, этот запрос:

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 и т. Д., Она не сможет выполнить преобразование и поэтому даст вам эту ошибку.

Вы можете запустить этот запрос, чтобы найти «значение проблемы», я думаю, что все, что строки возвращаются недавно были вставлены, вызывая ошибку:

Fiddle: http://sqlfiddle.com/#!4/f5b55/1/0

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