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, а не SQL NULL
) и *sqlind
в 0 (для NOT NULL
).
Оба параметра (проверка на NULL): установка *sqldata
в null
(указатель null, а не SQL NULL
) и *sqlind
в -1 (индикация NULL
).
Другими словами: значение параметра сравнения всегда устанавливается как обычно.SQL_NULL
параметр устанавливается также, за исключением случая, когда sqldata
передаётся как null
.