Тип данных SQL_NULL
Данный тип данных содержит не данные, а только состояние: NULL
или NOT NULL
.Также, этот тип данных не может быть использован при объявлении полей таблицы, переменных PSQL, использован в описании параметров.Этот тип данных добавлен для улучшения поддержки нетипизированных параметров в предикате IS NULL
.Такая проблема возникает при использовании “отключаемых фильтров” при написании запросов следующего типа:
WHERE col1 = :param1 OR :param1 IS NULL
после обработки, на уровне API запрос будет выглядеть как
WHERE col1 = ? OR ? IS NULL
В данном случае получается ситуация, когда разработчик при написании SQL запрос рассматривает :param1
как одну переменную, которую использует два раза, а на уровне API запрос содержит два отдельных и независимых параметра.Вдобавок к этому, сервер не может определить тип второго параметра, поскольку он идёт в паре с IS NULL
.
Именно для решения проблемы “? IS NULL” и был добавлен этот специальный тип данных SQL_NULL.
После введения данного специального типа данных при передаче запроса и его параметров на сервер будет работать такая схема: приложение передаёт параметризованные запросы на сервер в виде “?”.Это делает невозможным слияние пары “одинаковых” параметров в один.Так, например, для двух фильтров (двух именованных параметров) необходимо передать четыре позиционных параметра (далее предполагается, что читатель имеет некоторое знакомство с Firebird API):
SELECT
SH.SIZE, SH.COLOUR, SH.PRICE
FROM SHIRTS SH
WHERE (SH.SIZE = ? OR ? IS NULL)
AND (SH.COLOUR = ? OR ? IS NULL)
После выполнения isc_dsql_describe_bind()
sqltype 2-го и 4-го параметров устанавливается в SQL_NULL.Как уже говорилось выше, сервер Firebird не имеет никакой информации об их связи с 1-м и 3-м параметрами — это полностью прерогатива программиста.Как только значения для 1-го и 3-го параметров были установлены (или заданы как NULL) и запрос подготовлен, каждая пара XSQLVARs должна быть заполнена следующим образом:
- Пользователь задал параметры
-
-
Первый параметр (сравнение значений): установка
*sqldata
в переданное значение и*sqlind
в0
(дляNOT NULL
); -
Второй параметр (проверка на NULL): установка
*sqldata
вnull
(указатель null, а не SQLNULL
) и*sqlind
в 0 (дляNOT NULL
).
-
- Пользователь оставил поле пустым
-
-
Оба параметра (проверка на NULL): установка
*sqldata
вnull
(указатель null, а не SQLNULL
) и*sqlind
в -1 (индикацияNULL
).
-
Другими словами: значение параметра сравнения всегда устанавливается как обычно.SQL_NULL
параметр устанавливается также, за исключением случая, когда sqldata
передаётся как null
.