Firebird Documentation Index → NULL в СУБД Firebird → Обработка NULL в UDF |
UDF (User Defined
Functions - функции, определяемые пользователем) - это
функции, которые не являются внутренними функциями ядра, они определены в
отдельных (внешних) модулях. СУБД Firebird сопровождается двумя
библиотеками UDF: ib_udf
(унаследованная от СУБД InterBase) и
fbudf
. Вы можете добавить другие
библиотеки, например купив их, скачав их из Интерента, или написав
самостоятельно. UDF не могут использоваться «автоматически»,
как встроенные функции, - сначала их нужно «декларировать» в
базе данных. Это так же верно и для UDF, которые поставляются в
стандартных библиотеках с СУБД Firebird.
Рассказ о том, как объявлять, использовать и писать UDF выходит за
пределы темы, рассматриваемой этим руководством. Однако, мы должны
предупредить вас, что UDF порой выполняют неожиданное преобразование
NULL
. Иногда это приводит к тому, что входной
NULL
конвертируется в обыкновенное значение, а в
других случаях происходит изменение верного входного значения, например,
''
(пустая строка), на
NULL
.
Основной причиной этой проблемы является «старый
стиль» вызова UDF, при котором невозможно передать
NULL
в качестве входного аргумента функции. Когда
вызывается такая функция, как LTRIM
(отсечение
слева) с аргументом NULL
, аргумент передается в
функцию в виде пустой строки. Изнутри функции нет
способа определить, является ли аргумент действительно пустой
строкой или значением NULL
. Что же в таком случае
делать автору функции? У него есть выбор: либо брать аргумент по
полученному значению, либо считать, что первоначально это был
NULL
и поступать с ним соответственно.
В зависимости от типа результата, вернуть
NULL
может быть возможным, даже если получить
NULL
невозможно. Таким образом, могут произойти
следующие неожиданные вещи:
Вы вызваете функцию с аргументом NULL
. Он
передается как значение, например, 0 или ''
.
Внутри функции этот аргумент не изменяется назад на
NULL
, и возвращается
не-NULL
результат.
Вы вызываете функцию с верным аргументом, таким как 0 или
''
. Он передается как есть (очевидно). Но код
функции предполагает, что это значение на самом деле представляет
собой NULL
, и, ввиду отсутствия других
ориентиров, трактует и возвращает его как
NULL
.
Оба преобразования являются не желательными, но второе, вероятно,
более не желательно, чем первое (лучше предположить значение для
NULL
, чем утерять верное значение). Если вернуться
к нашему примеру с LTRIM
: до версии Firebird 1.0.3
(включительно) эта функция возвращала NULL
, если вы
передавали ей пустую строку; а начиная с версии 1.5 она больше не
возвращает NULL
. В этих последних версиях строка
NULL
«обрезается» до пустой строки.
Это не правильно, но здесь выбрано меньшее из двух зол: в более ранней
версии верные пустые строки безжалостно превращались в
NULL
- строки с неизвестным значением.
Нежелательные преобразования, описанные выше, обычно случаются
только со старыми (давно существующими и не адаптировавшимися)
библиотеками UDF, но их существует довольно много (чаще всего
встречается в ib_udf
). Также,
ничего не предостерегает небрежного разработчика от подобных ошибок в
функциях нового стиля. Итак, если вы используете UDF и не знаете, как
функция ведет себя с аргументами, содержащими NULL
,
то:
Посмотрите на декларацию функции, чтобы увидеть, как передаются аргументы и возвращаются значения. Если там сказано «by descriptor», это должно быть безопасно (хотя осуществить дополнительную проверку никогда не помешает). Во всех остальных случаях обратитесь к остальным пунктам.
Если у вас есть исходный код и вы понимаете язык, на котором написана библиотека функций (например, C/C++), проверьте код функции.
Проверьте функцию на корректность ее работы с входным
параметром NULL
и с обычным входным параметром,
который может быть интерпретирован функцией как
NULL
(0 для числовых аргументов и/или
''
для строковых аргументов).
Если функция выполняет нежелательное преобразование
NULL
<-> не-NULL
, вы
должны учитывать это в вашем коде прежде, чем будете вызывать UDF
(смотрите также Проверка на
NULL
где-то в этом руководстве).
Декларации функций для сопровождающих библиотек UDF могут быть
найдены в подкаталоге Firebird bin/examples
(v. 1.0) или bin/UDF
(v. 1.5 и старше). Смотрите файлы с
расширением .sql
Чтобы больше узнать об UDF, обратитесь к InterBase 6.0 Developer's Guide (скачать бесплатно на http://www.ibphoenix.com/downloads/60DevGuide.zip), Using Firebird и Firebird Reference Guide (оба на CD), или Firebird Book. CD и книга могут быть приобретены через http://www.ibphoenix.com/.
Firebird Documentation Index → NULL в СУБД Firebird → Обработка NULL в UDF |