Читать интересную книгу Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 89 90 91 92 93 94 95 96 97 ... 238

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, если вы можете это сделать, полностью исключайте утверждения NOT во вложенных предикатах.

. ! .

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 как контекстные выражения. Обычно такие поля получаются из хранимых данных, хотя и не обязательно. Они могут быть константами или, в общем виде, контекстными переменными или значениями, получаемыми из контекстных переменных.

Поля, создаваемые в операторах

Когда выходной столбец создается с использованием выражения, он называется вычисляемым выходным столбцом. Выходное значение всегда используется только для чтения, потому что оно не является хранимым значением. Любое выражение, которое выполняет сравнение, вычисление или преобразование и возвращает в качестве результата единственное значение, может включать в себя и такие столбцы.

Такое часто происходит, когда выражение использует более одной "формулы" для получения результата. В одном из наших ранних примеров функция (EXTRACT()) и операция (конкатенация) были использованы для получения строки BIRTHDAY, которая была выходной в списке. Такие сложные выражения вовсе не являются редкими.

Алиасы получаемых полей и столбцов

Выражения, вывод подзапросов и константы могут быть использованы в Firebird для передачи получаемых, или "искусственных" полей, в выходные наборы. Для предоставления возможности назначать имена во время выполнения Firebird поддерживает стандарт SQL назначения алиасов столбцам, что позволяет выводить любые столбцы с алиасами из одного или более символов.

Например, следующий оператор

SELECT COL_ID, COLA || ',' ||COLB AS comput col

FROM TABLEA;

возвращает столбец с именем comput_col, являющийся конкатенацией значений двух столбцов, разделенных запятыми.

! ! !

ВНИМАНИЕ! Когда два столбца соединяются подобным образом в любом выражении, выходное поле будет NULL, если любой из столбцов является NULL. Это также является стандартным поведением SQL.

. ! .

В следующем примере используется скалярный подзапрос к другой таблице для создания выходного поля времени выполнения:

SELECT COL_ID,

COLA,

COLB,

(SELECT SOMECOL FROM TABLEB

WHERE UNIQUE_ID = '99') AS B_SOMECOL

FROM TABLEA

Скалярный (под)запрос - это тот, который возвращает значение одного столбца из одной строки. Подзапросы обсуждаются в главе 22.

Firebird позволяет стандарту слегка расслабиться в отношении ключевого слова AS - оно необязательно. Опускать его не рекомендуется, потому что это может усложнить поиск алиаса столбца в исходном коде.

Другая часть стандарта требует, чтобы вычисляемые столбцы или получаемые из оператора подзапроса были явно поименованы с помощью алиаса. Текущая версия сервера Firebird позволяет вам опускать имя алиаса для вычисляемых столбцов или столбцов, полученных из подзапроса. Для примера следующий запрос

SELECT CAST(CURRENT_DATE as VARCHAR(10)) || '-' || REGISTRATION

FROM AIRCRAFT;

генерирует такой вывод:

<пробельная титульная строка>

===============

2003- 01-01-GORILLA

2004- 02-28-KANGAROO

. . .

Одни рассматривают это как ошибку, другие - как особенность. Для администратора базы данных удобнее быстро создать запрос, не беспокоясь о деталях. Это строго не рекомендуется использовать как "особенность" в приложениях. Выходные столбцы без имени слишком часто приводят к ошибкам и двусмысленностям в клиентских интерфейсах. Те же самые сложности могут появиться в интерфейсах приложений, если вы используете один и тот же алиас более одного раза в одном выходе.

Константы и переменные в качестве вывода времени выполнения

Существует возможность "создавать" выходной столбец в операторе SELECT, используя выражение, в которое включены не столбцы, а константы или контекстные переменные и алиасы. В следующем тривиальном примере запрос добавляет к каждой строке столбец, содержащий константное значение 'This is just a demo':

SELECT

LAST_NAME,

FIRST_NAME,

'This is just a demo' AS DEMO_STRING

FROM MEMBERSHIP;

Тривиальность, как она проявляется в этом примере, может быть удобным способом настройки вывода, особенно при использовании в выражении CASE.

Использование контекстных переменных

Firebird имеет набор переменных, предоставляющих мгновенный снимок значений сервера. Как вы уже видели, многие из этих значений могут быть использованы в выражениях, выполняющих вычисления. Они также могут быть использованы в выражениях, сохраняющих их в столбцах базы данных, или в спецификациях COMPUTED BY (см. разд. "Объявление столбцов COMPUTED BY").

Контекстные переменные также могут быть использованы в выражениях выходного столбца для передачи серверного значения непосредственно клиенту или модулю PSQL. Например:

SELECT

LOG_ID,

L0G_DATE,

. . .

CURRENT_DATE AS BASE_DATE,

СURRENT_TRANSACTION AS BASE_TRANSACTI0N,

. . .

FROM LOG

WHERE . . .

Подробный список доступных переменных и примеры их использования см. в разд. "Контекстные переменные" главы 8.

Выражения, использующие CASE() и дружественные функции

Firebird предоставляет из стандарта SQL-99 синтаксис выражения CASE и двух его "сокращенных" производных функций - COALESCE() и NULLIF(). Выражение CASE() может быть использовано для вывода константного значения, условно определенного во время выполнения в соответствии со значением указанного столбца в текущей строке запрашиваемой таблицы.

CASE()

Функция CASE() позволяет сделать вывод для столбца зависимым от результата вычисления группы взаимоисключающих условий.

Доступность

DSQL, PSQL, ISQL, ESQL, Firebird 1.5 и выше. Любая платформа.

Синтаксис

CASE {<значение 1> | <пустое-предложение>}

WHEN {{NULL | <значение 2>} | <предикат-поиска> }

1 ... 89 90 91 92 93 94 95 96 97 ... 238
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри.
Книги, аналогичгные Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри

Оставить комментарий