Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
Значения по умолчанию для всех столбцов в Firebird допускают пустые значения. Если ваша база данных не была сознательно спроектирована для предотвращения хранения значений NULL, ваши выражения должны быть готовы встретить пустое значение.
NULL в выражениях
NULL не является значением, следовательно, он не может быть "равным" какому-либо значению. Например, воз такой предикат
WHERE (COL1 = NULL)
вернет ошибку, потому что оператор равенства не является действительным для NULL, NULL является состоянием, и правильным предикатом
WHERE (COL1 IS NULL)
Вы также можете выполнять проверку на непустое значение:
WHERE (COL1 IS NOT NULL)
Два NULL не равны один другому. При конструировании выражений помните о тех случаях, когда предикат будет сведен к виду:
WHERE <NULL result> = <NULL result>
Здесь результатом всегда будет ложь при сравнении двух NULL. Выражение типа
WHERE COL1 > NULL
будет ошибочным, потому что арифметический оператор недопустим для NULL.
NULL в вычислениях
В выражении пустой операнд даст результат вычисления NULL. Например, следующий оператор
UPDATE TABLEA
SET COL4 = COL4 + C0L5;
присвоит столбцу COL4 значение NULL, если значением COL5 является NULL.
В агрегатном (обобщающем) выражении, использующем операторы типа SUMO, AVG или COUNT (<ИМЯ столбца>), строки, содержащие NULL В соответствующем столбце, будут проигнорированы, AVG сформирует числитель, суммируя непустые значения, и знаменатель, подсчитывая строки, содержащие непустые значения.
Понимание истинности и ложности
Семантически, если предикат возвращает "неопределенность", это не является ни истиной, ни ложью. В SQL при этом утверждения разрешаются только в виде "истина" или "ложь" - утверждение, которое не вычисляется как "истина", рассматривается как "ложь".
Условие IF, неявно присутствующее в предикатах поиска, может вызвать у вас галлюцинацию, когда NOT используется во вложенном условии:
NOT <условие, дающее ложь> дает TRUE
в то время как
NOT <условие, дающее NULL> дает NULL
Чтобы получить пример, когда наши предположения могут оказаться ошибочными, рассмотрим следующее:
WHERE
NOT (COLUMNA = COLUMNB)
Если оба столбца COLUMNA и COLUMNB имеют значения и не равны, вычисление внутреннего предиката (того, что заключен в скобки) даст "ложь". Утверждение NOT (FALSE) вернет истину - противоположность ложного значения.
Однако если любой из столбцов является NULL, внутренний предикат даст NULL, имеющий семантическое значение "неопределенный" ("непроверенный", "неопознаваемый"). Окончательное утверждение будет NOT (NULL), а результатом станет NULL. Обратите также внимание, что NOT (NULL) не является тем же самым, что и IS NOT NULL- чисто бинарный предикат, который никогда не вернет "неопределенное значение".
! ! !
ВНИМАНИЕ! Этот урок заключается в том, что нужно быть внимательным при работе с логикой SQL и всегда жестко проверять ваши выражения. Учитывайте условия NULL,
. ! .
NULL и внешние функции (UDF)
NULL не может передавать в виде входа или выхода функции в большинстве библиотек внешних функций, потому что они следуют соглашению InterBase о передаче аргументов по ссылке или по значению. Большинство доступных библиотек UDF используют это соглашение InterBase.
Сервер Firebird способен передавать аргументы в UDF по дескриптору. Это механизм, который стандартизует аргументы типов данных Firebird, делая возможным передачу NULL в качестве аргумента кода включающего языка, хотя и не предоставляя возможности получать NULL В качестве возвращаемого значения. Функции в библиотеке fbudf (в каталоге /UDF инсталляции сервера) используют дескрипторы.
Установка значения в NULL
Элемент данных может быть сделан NULL только в столбце, для которого не указано ограничение NOT NULL (СМ. разд. "Ограничение NOT NULL" главы 16).
В операторе UPDATE символом назначения является "=":
UPDATE FOO SET COL3 = NULL
WHERE COL2 = 4;
В операторе INSERT передавайте ключевое слово NULL на месте значения:
INSERT INTO FOO (COL1, COL2, COL3)
VALUES (1, 2, NULL);
для столбца.
! ! !
ПРИМЕЧАНИЕ. В этом случае NULL перекрывает любое значение по умолчанию
. ! .
Другой способ помещения NULL С помощью оператора INSERT - опустить имя столбца, допускающего пустое значение, во входном списке. Например, следующий оператор будет иметь тот же эффект, что и предыдущий, если значение по умолчанию не определено для столбца COL3:
INSERT INTO FOO (COL1, COL2)
VALUES (1, 2);
В PSQL (языке хранимых процедур) используйте символ "=" в качестве оператора присваивания при назначении переменной NULL, используйте is [NOT] NULL в предикате проверки IF:
. . .
DECLARE VARIABLE foobar integer;
. . .
IF (COL1 IS NOT NULL) THEN
FOOBAR = NULL;
Использование выражений
Вычисляемые столбцы
Полезной возможностью SQL является способность генерировать во время выполнения выходные поля с использованием выражений. Firebird поддерживает два вида вычисляемого вывода: поля, создаваемые в операторах DML, и столбцы, которые с помощью DDL были определены в таблице с использованием ключевых слов COMOTED BY как контекстные выражения. Обычно такие поля получаются из хранимых данных, хотя и не обязательно. Они могут быть константами или, в общем виде, контекстными переменными или значениями, получаемыми из контекстных переменных.