Кто может создать функцию?
Выполнить оператор CREATE FUNCTION
могут:
-
Пользователи с привилегией
CREATE FUNCTION
.
Пользователь, создавший хранимую функцию, становится её владельцем.
Выполнить оператор CREATE FUNCTION
могут:
Пользователи с привилегией CREATE FUNCTION
.
Пользователь, создавший хранимую функцию, становится её владельцем.
CREATE FUNCTION ADD_INT(A INT, B INT DEFAULT 0)
RETURNS INT
AS
BEGIN
RETURN A+B;
END
Вызов в запросе:
SELECT ADD_INT(2, 3) AS R FROM RDB$DATABASE
Вызов внутри PSQL кода, второй необязательный параметр не указан:
MY_VAR = ADD_INT(A);
CREATE FUNCTION FN_E()
RETURNS DOUBLE PRECISION DETERMINISTIC
AS
BEGIN
RETURN EXP(1);
END
Функция, возвращающая имя мнемоники по имени столбца и значения мнемоники.
CREATE FUNCTION GET_MNEMONIC (
AFIELD_NAME TYPE OF COLUMN RDB$TYPES.RDB$FIELD_NAME,
ATYPE TYPE OF COLUMN RDB$TYPES.RDB$TYPE)
RETURNS TYPE OF COLUMN RDB$TYPES.RDB$TYPE_NAME
AS
BEGIN
RETURN (SELECT RDB$TYPE_NAME
FROM RDB$TYPES
WHERE RDB$FIELD_NAME = :AFIELD_NAME
AND RDB$TYPE = :ATYPE);
END
То же самое, но хранимая функция будет выполняться с привилегиями определяющего пользователя (владельца функции).
CREATE FUNCTION GET_MNEMONIC (
AFIELD_NAME TYPE OF COLUMN RDB$TYPES.RDB$FIELD_NAME,
ATYPE TYPE OF COLUMN RDB$TYPES.RDB$TYPE)
RETURNS TYPE OF COLUMN RDB$TYPES.RDB$TYPE_NAME
SQL SECURITY DEFINER
AS
BEGIN
RETURN (SELECT RDB$TYPE_NAME
FROM RDB$TYPES
WHERE RDB$FIELD_NAME = :AFIELD_NAME
AND RDB$TYPE = :ATYPE);
END
Создание функции находящейся во внешнем модуле (UDR). Реализация функции расположена во внешнем модуле udrcpp_example.Имя функции внутри модуля — wait_event.
CREATE FUNCTION wait_event (
event_name varchar(63) CHARACTER SET ascii
) RETURNS INTEGER
EXTERNAL NAME 'udrcpp_example!wait_event'
ENGINE udr
Создание функции для перевода числа в шестнадцатеричный формат.
CREATE FUNCTION INT_TO_HEX (
ANumber BIGINT,
AByte_Per_Number SMALLINT = 8)
RETURNS CHAR(66)
AS
DECLARE VARIABLE xMod SMALLINT;
DECLARE VARIABLE xResult VARCHAR(64);
DECLARE FUNCTION TO_HEX(ANum SMALLINT) RETURNS CHAR
AS
BEGIN
RETURN CASE ANum
WHEN 0 THEN '0'
WHEN 1 THEN '1'
WHEN 2 THEN '2'
WHEN 3 THEN '3'
WHEN 4 THEN '4'
WHEN 5 THEN '5'
WHEN 6 THEN '6'
WHEN 7 THEN '7'
WHEN 8 THEN '8'
WHEN 9 THEN '9'
WHEN 10 THEN 'A'
WHEN 11 THEN 'B'
WHEN 12 THEN 'C'
WHEN 13 THEN 'D'
WHEN 14 THEN 'E'
WHEN 15 THEN 'F'
ELSE NULL
END;
END
BEGIN
xMod = MOD(ANumber, 16);
ANumber = ANumber / 16;
xResult = TO_HEX(xMod);
WHILE (ANUMBER > 0) DO
BEGIN
xMod = MOD(ANumber, 16);
ANumber = ANumber / 16;
xResult = TO_HEX(xMod) || xResult;
END
RETURN '0x' || LPAD(xResult, AByte_Per_Number * 2, '0');
END
Входные параметры заключаются в скобки после имени хранимой функции.Они передаются в функцию по значению, то есть любые изменения входных параметров внутри функции никак не повлияет на значения этих параметров в вызывающей программе.
У каждого параметра указывается тип данных.Кроме того, для параметра можно указать ограничение NOT NULL
, тем самым запретив передавать в него значение NULL
.
Для параметра строкового типа существует возможность задать порядок сортировки с помощью предложения COLLATE
.
Входные параметры могут иметь значение по умолчанию.Параметры, для которых заданы значения, должны располагаться в конце списка параметров.
В качестве типа параметра можно указать имя домена.В этом случае параметр будет наследовать все характеристики домена.
Если перед названием домена дополнительно используется предложение TYPE OF
, то используется только тип данных домена — не проверяется (не используется) его ограничение (если оно есть в домене) на NOT NULL
, CHECK
ограничения и/или значения по умолчанию.Если домен текстового типа, то всегда используется его набор символов и порядок сортировки.
Входные и выходные параметры можно объявлять, используя тип данных столбцов существующих таблиц и представлений.Для этого используется предложение TYPE OF COLUMN
, после которого указывается имя таблицы или представления и через точку имя столбца.
При использовании TYPE OF COLUMN
наследуется только тип данных, а в случае строковых типов ещё и набор символов, и порядок сортировки.Ограничения и значения по умолчанию столбца никогда не используются.
Предложение RETURNS
задаёт тип возвращаемого значения хранимой функции.Если функция возвращает значение строкового типа, то существует возможность задать порядок сортировки с помощью предложения COLLATE
.В качестве типа выходного значения можно указать имя домена, ссылку на его тип (с помощью предложения TYPE OF
) или ссылку на тип столбца таблицы (с помощью предложения TYPE OF COLUMN
).
Необязательное предложение DETERMINISTIC
указывает, что функция детерминированная.Детерминированные функции каждый раз возвращают один и тот же результат, если предоставлять им один и тот же набор входных значений.Недетерминированные функции могут возвращать каждый раз разные результаты, даже если предоставлять им один и тот же набор входных значений.Если для функции указано, что она является детерминированной, то такая функция не вычисляется заново, если она уже была вычислена однажды с данным набором входных аргументов, а берет свои значения из кэша метаданных (если они там есть).
Note
|
На самом деле в текущей версии Firebird, не существует кэша хранимых функций с маппингом входных аргументов на выходные значения. Указание инструкции Это легко демонстрируется таким примером:
|
Необязательное предложение SQL SECURITY
позволяет задать с какими привилегиями выполняется хранимая функция.Если выбрана опция INVOKER
, то хранимая функция выполняется с привилегиями вызывающего пользователя.Если выбрана опция DEFINER
, то хранимая функция выполняется с привилегиями определяющего пользователя (владельца функции). Эти привилегии будут дополнены привилегиями выданные самой хранимой функции с помощью оператора GRANT
.По умолчанию хранимая функция выполняется с привилегиями вызывающего пользователя.
Tip
|
Привилегии выполнения по умолчанию для вновь создаваемых объектов метаданных можно изменить с помощью оператора ALTER DATABASE SET DEFAULT SQL SECURITY {DEFINER | INVOKER} |
После ключевого слова AS
следует тело хранимой функции.
В необязательной секции <declarations> описаны локальные переменные функции, именованные курсоры и подпрограммы (подпроцедуры и подфункции). Локальные переменные подчиняются тем же правилам, что и входные параметры функции в отношении спецификации типа данных.Подробности вы можете посмотреть в главе “Процедурный язык PSQL”в разделах DECLARE VARIABLE иDECLARE CURSOR,DECLARE PROCEDURE,DECLARE FUNCTION.
После необязательной секции деклараций обязательно следует составной оператор.Составной оператор состоит из одного или нескольких PSQL операторов, заключенных между ключевыми словами BEGIN
и END
.Составной оператор может содержать один или несколько других составных операторов.Вложенность ограничена 512 уровнями.Любой из BEGIN … END
блоков может быть пустым, в том числе и главный блок.
Хранимая функция может быть расположена во внешнем модуле.В этом случае вместо тела функции указывается место расположения функции во внешнем модуле с помощью предложения EXTERNAL NAME
.Аргументом этого предложения является строка, в которой через разделитель указано имя внешнего модуля, имя функции внутри модуля и определённая пользователем информация.В предложении ENGINE
указывается имя движка для обработки подключения внешних модулей.В Firebird для работы с внешними модулями используется движок UDR.После ключевого слова AS
может быть указан строковый литерал — "тело" внешней функции, оно может быть использовано внешним модулем для различных целей.
Warning
|
Не следует путать внешние функции, объявленные как |
ALTER FUNCTION
Изменение существующей хранимой функции.
DSQL
ALTER FUNCTION funcname [(<inparam> [, <inparam> ...])] RETURNS <type> [COLLATE collation] [DETERMINISTIC] <routine-body> Подробнее см. CREATE FUNCTION.
Оператор ALTER FUNCTION
позволяет изменять состав и характеристики входных параметров, типа выходного значения, локальных переменных, именованных курсоров, подпрограмм и тело хранимой функции.Для внешних функций (UDR) вы можете изменить точку входа и имя движка.Внешние функции, объявленные как DECLARE EXTERNAL FUNCTION
, так же известные как UDF, невозможно преобразовать в PSQL функции и наоборот.После выполнения существующие привилегии и зависимости сохраняются.
Note
|
Будьте осторожны при изменении количества и типов входных параметров хранимых функций.Существующий код приложения может стать неработоспособным из-за того, что формат вызова функции несовместим с новым описанием параметров.Кроме того, PSQL модули, использующие изменённую хранимую функцию, могут стать некорректными.Информация о том, как это обнаружить, находится в приложении Поле RDB$VALID_BLR. |
Warning
|
Если у вас уже есть внешняя функция в Legacy стиле ( |
Выполнить оператор ALTER FUNCTION
могут:
Владелец хранимой функции;
Пользователи с привилегией ALTER ANY FUNCTION
.
ALTER FUNCTION ADD_INT(A INT, B INT, C INT)
RETURNS INT
AS
BEGIN
RETURN A+B+C;
END
CREATE OR ALTER FUNCTION
Создание новой или изменение существующей хранимой функции.
DSQL
CREATE OR ALTER FUNCTION funcname [(<inparam> [, <inparam> ...])] RETURNS <type> [COLLATE collation] [DETERMINISTIC] <routine-body> Подробнее см. CREATE FUNCTION.
Оператор CREATE OR ALTER FUNCTION
создаёт новую или изменяет существующую хранимую функцию.Если хранимая функция не существует, то она будет создана с использованием предложения CREATE FUNCTION
.Если она уже существует, то она будет изменена и перекомпилирована, при этом существующие привилегии и зависимости сохраняются.
Warning
|
Если у вас уже есть внешняя функция в Legacy стиле ( |
CREATE OR ALTER FUNCTION ADD_INT(A INT, B INT DEFAULT 0)
RETURNS INT
AS
BEGIN
RETURN A+B;
END
DROP FUNCTION
Удаление хранимой функции.
DSQL
DROP FUNCTION funcname
Параметр | Описание |
---|---|
funcname |
Имя хранимой функции. |
Оператор DROP FUNCTION
удаляет существующую хранимую функцию.Если от хранимой функции существуют зависимости, то при попытке удаления такой функции будет выдана соответствующая ошибка.
Выполнить оператор DROP FUNCTION
могут:
Владелец хранимой функции;
Пользователи с привилегией DROP ANY FUNCTION
.
RECREATE FUNCTION
Создание новой или пересоздание существующей хранимой функции.
DSQL
RECREATE FUNCTION funcname [(<inparam> [, <inparam> ...])] RETURNS <type> [COLLATE collation] [DETERMINISTIC] <routine-body> Подробнее см. CREATE FUNCTION
Оператор RECREATE FUNCTION
создаёт новую или пересоздаёт существующую хранимую функцию.Если функция с таким именем уже существует, то оператор попытается удалить её и создать новую функцию.Операция закончится неудачей при подтверждении транзакции, если функция имеет зависимости.
Note
|
Имейте в виду, что ошибки зависимостей не обнаруживаются до фазы подтверждения транзакции. |
После пересоздания функции привилегии на выполнение хранимой функции и привилегии самой хранимой функции не сохраняются.
RECREATE FUNCTION ADD_INT(A INT, B INT DEFAULT 0)
RETURNS INT
AS
BEGIN
RETURN A+B;
END