Как обрабатывать нули в операторах NOT IN и NOT LIKE в Oracle?

У меня есть длинный кусок PL/SQL, который работает хорошо, за исключением одной небольшой части предложения where.

Я ожидаю, что должна быть возвращена одна строка, но, поскольку поля, в которых проверяется предложение, имеют значение null, строка не возвращается, несмотря на соответствие критериям.

Я прочитал здесь очень хорошую заметку:
http://jonathanlewis.wordpress.com/2007/02/25/not-in/

Это объясняет, как Nulls влияют на операторы NOT IN, и я предполагаю, что то же самое и для NOT LIKE.

Чего я не смог найти, так это сопоставимой замены, которая мне нужна. Нужно ли мне каким-то образом переключить это на IN и LIKE или предоставить что-то, чтобы вернуть строку, если NUll?

Вот упрощенная версия моего кода.

SELECT * FROM Temp_Table T
WHERE -- Other where constraints
AND (T.Col_One NOT LIKE 'AString'
     OR T.Col_Two NOT IN ('BString','CString'))

В моей ситуации строка будет иметь нули как в Col_One, так и в Col_Two.

Любая помощь приветствуется.

Спасибо.


person dee    schedule 26.06.2012    source источник


Ответы (4)


Попробуй это:

AND (NVL(T.Col_One,'NuLl') NOT LIKE 'AString'
      OR NVL(T.Col_Two,'NuLl') NOT IN ('BString','CString')) 
person DCookie    schedule 26.06.2012
comment
Проверено, и это сработало отлично. Спасибо за быстрый ответ. Я был обеспокоен тем, что на самом деле он может вставить «NuLl» в качестве значения, но оно используется только для сравнения. Спасибо еще раз. - person dee; 27.06.2012
comment
Это не общее решение. Хотя в этом случае мы знаем, что «AString» не может быть «NuLl», в реальной жизни это, вероятно, будет связанным параметром, и клиентское приложение должно будет гарантировать, что «NuLl» ему никогда не будет передано. Лучше просто явно проверять значения NULL и избегать любой зависимости от магических значений. - person Branko Dimitrijevic; 27.06.2012
comment
@Branko, хороший комментарий, вы правы, и ваше решение, вероятно, также более производительно, поскольку оно может закоротить при первой нулевой проверке. - person DCookie; 27.06.2012

Что-то вроде этого должно работать:

T.Col_One IS NULL OR T.Col_One NOT LIKE 'AString'
OR T.Col_Two IS NULL OR T.Col_Two NOT IN ('BString','CString')

Обратите внимание, что...

T.Col_Two NOT IN ('BString','CString') 

...эквивалентно...

T.Col_Two <> 'BString' AND T.Col_Two <> 'CString'

... который "сворачивается" до NULL в случае, если T.Col_Two равен NULL.

person Branko Dimitrijevic    schedule 26.06.2012
comment
Да, мне приходится постоянно напоминать себе, что НЕ ВНУТРИ — это не то же самое, что ВНУТРИ. Спасибо. - person dee; 27.06.2012

По соглашению NULL не является like или чем-то равным - единственным допустимым тестом будет IS NULL, который вернет true.

person Richard Harrison    schedule 26.06.2012

Проверьте функцию NVL в документации Oracle по адресу: http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions105.htm

person dcasanueva    schedule 26.06.2012