| 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 |