Внешние функции, также известные как функции определяемые пользователем (User Defined Function) — это программы, написанные на любом языке программирования, и хранящиеся в динамических библиотеках. После того как функция объявлена в базе данных, она становится доступной в динамических и процедурных операторах, как будто они реализованы внутри языка SQL.
Внешние функции существенно расширяют возможности SQL по обработке данных.
Для того чтобы функции были доступны в базе данных, их необходимо объявить с помощью оператора DECLARE EXTERNAL FUNCTION
.
После объявления функции, содержащая её библиотека будет загружаться при первом обращении к любой из функций, включённой в библиотеку.
Important
|
Внешние функции (UDF) объявлены устаревшими в Firebird 4:
|
Caution
|
UDF принципиально небезопасны.
Мы рекомендуем по возможности избегать их использования и отключать UDF в конфигурации вашей базы данных ( |
Объявление в базе данных функции определённой пользователем (UDF).
DSQL, ESQL
DECLARE EXTERNAL FUNCTION funcname [{ <arg_desc_list> | ( <arg_desc_list> ) }] RETURNS { <return_value> | ( <return_value> ) } ENTRY_POINT 'entry_point' MODULE_NAME 'library_name' <arg_desc_list> ::= <arg_type_decl> [, <arg_type_decl> ...] <arg_type_decl> ::= <udf_data_type> [BY {DESCRIPTOR | SCALAR_ARRAY} | NULL] <udf_data_type> ::= <scalar_datatype> | BLOB | CSTRING(length) [ CHARACTER SET charset ] <return_value> ::= <udf_data_type> { BY VALUE | BY DESCRIPTOR [FREE_IT] | FREE_IT } | PARAMETER param_num <scalar_datatype> ::= См. Синтаксис скалярных типов данных
DECLARE EXTERNAL FUNCTION
Параметр | Описание |
---|---|
funcname |
Имя внешней функции. Может содержать до 63 символов. |
entry_point |
Имя экспортируемой функции (точка входа). |
library_name |
Имя модуля, в котором расположена функция. |
sqltype |
Тип данных SQL. Не может быть массивом или элементом массива. |
length |
Максимальная длина нуль терминальной строки. Указывается в байтах. |
charset |
Кодировка строки. |
param_num |
Номер входного параметра, который будет возвращён функцией. |
Оператор DECLARE EXTERNAL FUNCTION
делает доступным внешнюю функцию, определенную пользователем (UDF), в базе данных.
Внешние функции должны быть объявлены в каждой базе данных, которая собирается их использовать.
Не нужно объявлять UDF, если вы никогда не будете её использовать.
Имя внешней функции должно быть уникальным среди всех имён функций. Оно может отличаться от имени функции указанной в аргументе ENTRY_POINT.
Входные параметры функции перечисляются через запятую сразу после имени функции.
Для каждого параметра указывается SQL тип данных.
Помимо SQL типов можно указать тип CSTRING
.
В этом случае параметр является нуль терминальной строкой с максимальной длиной length байт.
Существует несколько механизмов передачи параметра из движка Firebird во внешнюю функцию, каждый из этих механизмов будет рассмотрен отдельно.
По умолчанию входные параметры передаются по ссылке. Не существует отдельного предложения для явного указания, что параметр передаётся по ссылке.
При передаче NULL
значения по ссылке оно преобразуется в эквивалент нуля, например, число 0 или пустую строку.
Если после указанного параметра указано ключевое слово NULL
, то при передаче значение NULL
оно попадёт в функцию в виде нулевого указателя (NULL).
Note
|
Обратите внимание на то, что объявление функции с ключевым словом NULL не гарантирует вам, что эта функция правильно обработает входной параметр со значением NULL. Любая функция должна быть написана или переписана таким образом, чтобы правильно обрабатывать значения NULL. Всегда смотрите и используйте объявления функции, предоставленные её разработчиком. |
Если указано предложение BY DESCRIPTOR
, то входной параметр передаётся по дескриптору.
В этом случае параметр UDF получит указатель на внутреннюю структуру, известную как дескриптор, несущую информацию о типе данных, подтипе, точности, наборе символов и сортировке, масштабе, указателе на сами данные и некоторых флагах, в том числе NULL индикаторе.
Отметим, что это объявление работает только в том случае, если внешняя функция написана с использованием дескриптора.
Warning
|
При передаче параметра функции по дескриптору передаваемое значение не приводится к задекларированному типу данных. |
Предложение BY SCALAR_ARRAY
используется при передаче массивов в качестве входных параметров.
В отличие от других типов, вы не можете вернуть массив из UDF.
Обязательное предложение RETURNS
описывает выходной параметр возвращаемый функцией.
Функция всегда возвращает только один параметр.
Выходной параметр может быть любым SQL типом (кроме массива и элемента массива) или нуль терминальной строкой (CSTRING
).
Выходной параметр может быть передан по ссылке, по дескриптору или по значению.
По умолчанию выходной параметр передаётся по ссылке.
Если указано предложение BY DESCRIPTOR
, то выходной параметр передаётся по дескриптору.
Если указано предложение BY VALUE
, то выходной параметр передаётся по значению.
Ключевое слово PARAMETER
указывает, что функция возвращает значение из параметра с номером param_num.
Такая необходимость возникает, если необходимо возвращать значение типа BLOB.
Ключевое слово FREE_IT
означает, что память, выделенная для хранения возвращаемого значения, будет освобождена после завершения выполнения функции.
Применяется только в том случае, если эта память в UDF выделялась динамически.
В такой UDF память должна выделяться при помощи функции ib_util_malloc из модуля ib_util.
Это необходимо для совместимости функций выделения и освобождения памяти используемого в коде Firebird и коде UDF.
Предложение ENTRY_POINT
указывает имя точки входа (имя экспортируемой функции) в модуле.
Предложение MODULE_NAME
задаёт имя модуля, в котором находится экспортируемая функция.
В ссылке на модуль может отсутствовать полный путь и расширение файла.
Это позволяет легче переносить базу данных между различными платформами.
По умолчанию динамические библиотеки пользовательских функций должны располагаться в папке UDF корневого каталога сервера.
Параметр UDFAccess
в файле firebird.conf позволяет изменить ограничения доступа к библиотекам внешних функций.
Выполнить оператор DECLARE EXTERNAL FUNCTION
могут:
-
Пользователи с привилегией
CREATE FUNCTION
.
Пользователь, объявивший внешнюю функцию, становится её владельцем.
DECLARE EXTERNAL FUNCTION addDay
TIMESTAMP, INT
RETURNS TIMESTAMP
ENTRY_POINT 'addDay' MODULE_NAME 'fbudf';
DECLARE EXTERNAL FUNCTION invl
INT BY DESCRIPTOR, INT BY DESCRIPTOR
RETURNS INT BY DESCRIPTOR
ENTRY_POINT 'idNvl' MODULE_NAME 'fbudf';
DECLARE EXTERNAL FUNCTION isLeapYear
TIMESTAMP
RETURNS INT BY VALUE
ENTRY_POINT 'isLeapYear' MODULE_NAME 'fbudf';
DECLARE EXTERNAL FUNCTION i64Truncate
NUMERIC(18) BY DESCRIPTOR, NUMERIC(18) BY DESCRIPTOR
RETURNS PARAMETER 2
ENTRY_POINT 'fbtruncate' MODULE_NAME 'fbudf';
ALTER EXTERNAL FUNCTION, DROP EXTERNAL FUNCTION, CREATE FUNCTION.
Изменение точки входа и/или имени модуля для функции определённой пользователем (UDF).
DSQL
ALTER EXTERNAL FUNCTION funcname [ENTRY_POINT 'new_entry_point'] [MODULE_NAME 'new_library_name'];
ALTER EXTERNAL FUNCTION
Параметр | Описание |
---|---|
funcname |
Имя внешней функции. |
new_entry_point |
Новое имя экспортируемой функции (точки входа). |
new_library_name |
Новое имя модуля, в котором расположена функция. |
Оператор ALTER EXTERNAL FUNCTION
изменяет точку вход и/или имя модуля для функции определённой пользователем (UDF). При этом существующие зависимости сохраняются.
Предложение ENTRY_POINT
позволяет указать новую точку входа (имя экспортируемой функции).
Предложение MODULE_NAME
позволяет указать новое имя модуля, в котором расположена экспортируемая функция.
Выполнить оператор ALTER EXTERNAL FUNCTION
могут:
-
Владелец внешней функции;
-
Пользователи с привилегией
ALTER ANY FUNCTION
.
ALTER EXTERNAL FUNCTION invl ENTRY_POINT 'intNvl';
ALTER EXTERNAL FUNCTION invl MODULE_NAME 'fbudf2';
Удаление объявления функции определённой пользователем (UDF) из базы данных.
DSQL, ESQL.
DROP EXTERNAL FUNCTION funcname
DROP EXTERNAL FUNCTION
Параметр | Описание |
---|---|
funcname |
Имя внешней функции. |
Оператор DROP EXTERNAL FUNCTION
удаляет объявление функции определённой пользователем из базы данных.
Если есть зависимости от внешней функции, то удаления не произойдёт и будет выдана соответствующая ошибка.
Выполнить оператор DROP EXTERNAL FUNCTION
могут:
-
Владелец внешней функции;
-
Пользователи с привилегией
DROP ANY FUNCTION
.
DROP EXTERNAL FUNCTION addDay;