Oracle для профессионалов



              

Независимость от СУБД? - часть 2


С подобными проблемами я сталкивался многократно при переносе приложений из СУБД А в СУБД Б. Когда приложение, без проблем работавшее в СУБД А, не работает или работает весьма странно в СУБД Б, сразу же возникает мысль, что "СУБД Б — плохая". Правда, однако, в том, что СУБД Б работает иначе. Ни одна из СУБД не ошибается и не является "плохой" — они просто разные. Знание и понимание особенностей их работы поможет успешно решить подобные проблемы.

Совсем недавно я помогал перевести код с языка Transact SQL (язык создания хранимых процедур для СУБД SQL Server) на PL/SQL. Разработчик, занимавшийся переводом, жаловался, что SQL-запросы в Oracle возвращают "неправильный" ответ. Запросы выглядели следующим образом:

declare l_some_variable varchar2(25); begin if ( some_condition ) then l_some_variable := f( ... ); end if;

for x in ( select * from T where x = l_some_variable ) loop ...

Целью является получение всех строк таблицы T, которые в столбце X имеют пустое значение, если некоторое условие не выполнено, или определенное значение, если это условие выполнено.

Суть жалобы состояла в том, что, в Oracle этот запрос не возвращал данных, если переменная L_SOME_VARIABLE не получала значения явно (когда у нее оставалось значение NULL). В СУБД Sybase или SQL Server все было не так — запрос находил строки с неопределенным (NULL) значением в столбце X. Я встречался с этим практически при любом переводе приложения с СУБД Sybase или SQL Server на Oracle. Язык SQL предполагает использование трехзначной логики, и СУБД Oracle реализует неопределенные значения так, как того требует стандарт ANSI SQL. По этим правилам сравнение столбца X со значением NULL не дает ни True, ни False — результат фактически неизвестен. Следующий пример показывает, что я имею в виду:

ops$tkyte@ORA8I.WORLD> select * from dual;

D - X

ops$tkyte@ORA8I.WORLD> select * from dual where null=null;

no rows selected

ops$tkyte@ORA8I.WORLD> select * from dual where null<>null;




Содержание  Назад  Вперед