Выберите строку как число в Oracle - PullRequest
9 голосов
/ 27 марта 2012

Я обнаружил это странное поведение, и я ломаю себе голову этим ... у кого-нибудь есть идеи?

Oracle 10g: у меня есть две разные таблицы, у обеих есть этот столбец с именем " TESTCOL "as Varchar2 (10) , не обнуляется.

Если я выполню этот запрос на table1 , я получу правильные результаты:

select * from table1 where TESTCOL = 1234;

Примечание , которое я специально не размещаю '1234 '... это не опечатка, это динамически сгенерированный запрос, и я постараюсь не менять его (по крайней мере, в ближайшем будущем).

Но, если я выполню тот же запрос, на table2 , я получаю это сообщение об ошибке:

ORA-01722: Invalid number

Оба запроса выполняются в одной и той же сессии, в одной и той же базе данных.

Я присоединился к этим двум таблицамстолбец и объединение работает нормально, единственная проблема появляется всякий раз, когда я пытаюсь использовать это условие.

Любые идеи о том, что может отличаться от одной таблицы к другой?

Заранее спасибо.

Ответы [ 4 ]

25 голосов
/ 27 марта 2012

Если TESTCOL содержит не числа, Oracle может столкнуться с проблемами при преобразовании записей TESTCOL в числа.Потому что то, что он делает внутренне, это:

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

Если вы уверены, что 1234 не может быть выражен как литерал VARCHAR, попробуйте это вместо этого, чтобы сравнить значения varchar., а не числовые:

select * from table1 where TESTCOL = TO_CHAR(1234);
5 голосов
/ 27 марта 2012

Хорошо очевидно, что TABLE2.TESTCOL содержит значения, которые не являются числами . Сравнение строки с числовым литералом создает неявное преобразование. Поэтому любое значение в TESTCOL, которое не может быть приведено к числу, будет отбрасывать ORA-1722.

Вас не поразит, где вы сравниваете две таблицы, потому что вы сравниваете строки.

Итак, у вас есть пара вариантов, ни один из которых вам не понравится. Самый очевидный ответ - очистить данные, чтобы таблица TABLE2 не содержала нечисловых значений. В идеале вы должны сочетать это с изменением столбца на числовой тип данных. В противном случае вы можете изменить генератор так, чтобы он генерировал код, который вы можете запускать на тонкой модели данных. В этом случае это означает перенос литералов в кавычки, если отображаемый столбец имеет символьный тип данных.

4 голосов
/ 27 марта 2012

Вы столкнулись с опасностями неявной типизации здесь.

С выражением testcol = 1234 вы заявляете, что хотите трактовать testcol как числовой столбец, поэтому Oracle пытается преобразовать все значения в этом столбце в число.

ORA-01722 происходит потому, что, по крайней мере, одно значение в этом столбце равно , а не число.

Даже если вы утверждаете, что это " не опечатка ", это действительно так.Это синтаксическая ошибка.

Вы должны будете объявить свой параметр как строковый литерал, используя одинарные кавычки: where testcol = '1234'

Создание правильного условия - единственное решение вашей проблемы.

0 голосов
/ 05 марта 2013

Следующее должно работать. Просто замените «ваше где».

select * 
from table1 
where (select TO_NUMBER(TESTCOL) 
       from table2 
       where "your where") = 1234;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...