Хранимые функции (FUNCTION)

Хранимая функция подобно хранимой процедуре является программой, хранящаяся в базе данных и выполняющейся на стороне сервера.

В отличие от хранимых процедур хранимые функции всегда возвращают одно скалярное значение. Для возврата значения из хранимой функции используется оператор RETURN, который немедленно прекращает выполнение функции.

Хранимые функции работают практически также, как и обычные встроенные скалярные функции (например, UPPER, SIN, RAND, …). Их можно использовать в списке выбора SELECT, в условиях WHERE или ORDER BY и т.п.

Создание хранимой функции

Для создания хранимой функции используется оператор CREATE FUNCTION.

CREATE FUNCTION <имя хранимой функции>
   [(<входной параметр> [, <входной параметр> ...])]
RETURNS <тип> [DETERMINISTIC]
AS
   [<объявление> [<объявление> ...] ]
BEGIN
   <блок операторов>
END

Хранимой функции от вызвавшей программы могут передаваться входные параметры. Параметры передаются по значению, то есть любые изменения значений входных параметров никак не влияют на значения этих параметров в вызвавшей программе. Входным параметрам может присваиваться значение по умолчанию. Параметры, для которых заданы значения по умолчанию, должны располагаться в самом конце списка.

Предложение RETURNS задаёт тип возвращаемого значения хранимой функции.

Необязательное предложение DETERMINISTIC указывает, что функция детерминированная. Детерминированные функции каждый раз возвращают один и тот же результат, если предоставлять им один и тот же набор входных значений. Недетерминированные функции могут возвращать каждый раз разные результаты, даже если предоставлять им один и тот же набор входных значений. Если для функции указано, что она является детерминированной, то такая функция не вычисляется заново, если она уже была вычислена однажды с данным набором входных аргументов, а берет свои значения из кэша метаданных (если они там есть).

Для изменения существующей хранимой функции используется оператор ALTER FUNCTION.

ALTER FUNCTION <имя хранимой функции>
   [(<входной параметр> [, <входной параметр> ...])]
RETURNS <тип> [DETERMINISTIC]
AS
   [<объявление> [<объявление> ...] ]
BEGIN
   <блок операторов>
END

После выполнения существующие привилегии и зависимости сохраняются.

Параметр DETERMINISTIC можно изменять без указания тела функции:

ALTER FUNCTION <имя хранимой функции> {DETERMINISTIC | NOT DETERMINISTIC}

Допускается также и одновременное создание или обновление хранимой функции в зависимости от того, существует ли уже функция с таким названием или нет.

CREATE OR ALTER FUNCTION <имя хранимой функции>
   [(<входной параметр> [, <входной параметр> ...])]
RETURNS <тип> [DETERMINISTIC]
AS
   [<объявление> [<объявление> ...] ]
BEGIN
   <блок операторов>
END

Для удаления существующей хранимой функции используется оператор DROP FUNCTION.

DROP FUNCTION <имя хранимой процедуры>

Если от хранимой функции существуют зависимости, то при попытке удаления такой функции будет выдана соответствующая ошибка.

В качестве примера рассмотрим создание простой детерминированной хранимой функции, которая вычисляет площадь окружности по ее радиусу.

CREATE FUNCTION CIRCLE_SQUARE(R DOUBLE PRECISION)
   RETURNS DOUBLE PRECISION
   DETERMINISTIC
AS
BEGIN
   RETURN PI() * R * R;
END

Использовать такую функцию можно, например, в таком запросе:

SELECT CIRCLE_SQUARE(10) FROM RDB$DATABASE

Который вернет,

CIRCLE_SQUARE
314.1592653589793

Контрольные вопросы

  1. В чем отличие хранимой функции от хранимой процедуры?
  2. Когда и зачем указывается опция DETERMINISTIC?
  3. Как и где можно вызывать хранимые функции?