CREATE PROCEDURE

CREATE PROCEDURE — определить новую процедуру


Синтаксис

CREATE [ OR REPLACE ] PROCEDURE
    имя ( [ [ режим_аргумента ] [ имя_аргумента ] тип_аргумента [ { DEFAULT | = } выражение_по_умолчанию ] [, ...] ] )
  { LANGUAGE имя_языка
    | TRANSFORM { FOR TYPE имя_типа } [, ... ]
    | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
    | SET параметр_конфигурации { TO значение | = значение | FROM CURRENT }
    | AS 'определение'
    | AS 'объектный_файл', 'ссылочный_символ'
    | тело_sql  
  } ...

Описание

Команда CREATE PROCEDURE определяет новую процедуру. CREATE OR REPLACE PROCEDURE либо создаст новую процедуру, либо заменит существующее определение. Чтобы иметь возможность определить процедуру, необходимо иметь право USAGE для соответствующего языка.

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

Чтобы заменить текущее определение существующей процедуры, используйте CREATE OR REPLACE PROCEDURE. Таким способом невозможно изменить имя или типы аргументов процедуры (если вы попытаетесь, то фактически создадите новую, отдельную процедуру).

Если CREATE OR REPLACE PROCEDURE используется для замены существующей процедуры, владелец и права доступа к этой процедуре не меняются. Всем остальным свойствам процедуры присваиваются значения, указанные в команде явно или подразумеваемые по умолчанию. Чтобы заменить процедуру, нужно быть ее владельцем (или быть членом роли-владельца).

Пользователь, создающий процедуру, становится ее владельцем.

Чтобы создать процедуру, необходимо иметь право USAGE для типов ее аргументов.

Более подробную информацию о написании процедур см. в разделе Пользовательские процедуры.


Параметры

имя

Имя создаваемой процедуры (может быть дополнено схемой).

режим_аргумента

Режим аргумента: IN (входной), OUT (выходной), INOUT (входной и выходной) или VARIADIC (переменный). Если этот параметр опущен, значение по умолчанию равно IN.

имя_аргумента

Имя аргумента.

тип_аргумента

Тип данных аргументов процедуры (при необходимости дополненный схемой), если аргументы имеются. Типы аргументов могут быть базовыми, составными или доменными типами, а также могут ссылаться на тип столбца таблицы.

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

Ссылка на тип столбца записывается в виде имя_таблицы.имя_столбца%TYPE. Использование этой возможности иногда может помочь сделать процедуру независимой от изменений в определении таблицы.

выражение_по_умолчанию

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

имя_языка

Имя языка, на котором реализована процедура. Это может быть sql, c, internal или имя пользовательского процедурного языка, например plpgsql. Если указано тело_sql, языком по умолчанию является sql. Заключение имени в апострофы считается устаревшим вариантом и требует совпадения регистра.

TRANSFORM { FOR TYPE имя_типа } [, ... ] }

Устанавливает список трансформаций, которые должны применяться при вызове процедуры. Трансформации выполняют преобразования между типами SQL и типами данных, специфичными для языков; см. справочную страницу команды CREATE TRANSFORM. Преобразования встроенных типов обычно жестко предопределены в реализациях процедурных языков, так что их здесь указывать не нужно. Если реализация процедурного языка не знает, как обрабатывать тип, и трансформация не предоставляется, будет выполнено преобразование типов данных по умолчанию, но это зависит от реализации.

[EXTERNAL] SECURITY INVOKER
[EXTERNAL] SECURITY DEFINER

Характеристика SECURITY INVOKER (безопасность вызывающего) указывает, что процедура должна выполняться с правами вызывающего ее пользователя. Это значение по умолчанию. Вариант SECURITY DEFINER (безопасность определившего) указывает, что процедура должна выполняться с правами пользователя, который ей владеет.

Ключевое слово EXTERNAL (внешняя) допускается для соответствия стандарту SQL, но является необязательным, так как, в отличие от SQL, эта характеристика распространяется на все процедуры, а не только на внешние.

В процедуре с характеристикой SECURITY DEFINER не могут выполняться операторы управления транзакциями (например COMMIT и ROLLBACK в некоторых языках).

параметр_конфигурации
значение

Предложение SET определяет, что при вызове процедуры указанный параметр конфигурации должен принять заданное значение, а затем, по завершении процедуры, восстановить свое предыдущее значение. Предложение SET FROM CURRENT сохраняет значение параметра, действующее при выполнении CREATE PROCEDURE, в качестве значения, которое будет применено при входе в процедуру.

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

Если к определению процедуры добавлено предложение SET, то в этой процедуре не смогут выполняться операторы управления транзакциями (например COMMIT и ROLLBACK в некоторых языках).

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

определение

Строковая константа, определяющая процедуру; значение зависит от языка. Это может быть имя внутренней процедуры, путь к объектному файлу, команда SQL или код на процедурном языке.

Часто бывает полезно заключать определение процедуры в знаки доллара (см. подраздел Строковые константы с экранированием знаками доллара), а не в традиционные апострофы. Если не использовать знаки доллара, то любые апострофы или обратные слэши в определении процедуры должны быть экранированы путем удвоения.

объектный_файл, ссылочный_символ

Это форма предложения AS используется для динамически загружаемых процедур на языке C/RUST, когда имя процедуры в исходном коде на языке C/RUST не совпадает с именем процедуры SQL. Строка объектный_файл является именем файла разделяемой библиотеки, содержащего скомпилированную процедуру на C/RUST, и интерпретируется как параметр команды LOAD. Строка ссылочный_символ задает ссылочный символ процедуры, то есть имя процедуры в исходном коде на языке C/RUST. Если ссылочный символ опущен, предполагается, что он совпадает с именем определяемой процедуры SQL.

При повторных вызовах CREATE PROCEDURE ссылается на один и тот же объектный файл, который загружается только один раз за сеанс. Чтобы выгрузить и перезагрузить файл (возможно, во время разработки), запустите новый сеанс.

тело_sql

Тело функции в стиле LANGUAGE SQL. Это должен быть блок операторов

BEGIN ATOMIC
  оператор;
  оператор;
  ...
  оператор;
END

Это схоже с написанием текста тела процедуры в виде строковой константы (см. определение выше), но есть некоторые различия: эта форма работает только для LANGUAGE SQL, а форма строковой константы работает для всех языков. Эта форма анализируется во время определения процедуры, а форма строковой константы анализируется во время выполнения; таким образом, эта форма не может поддерживать полиморфные типы аргументов и другие конструкции, которые нельзя разрешить во время определения процедуры. Эта форма отслеживает зависимости между процедурой и объектами, используемыми в ее теле, так что команда DROP ... CASCADE будет работать корректно, тогда как форма, использующая строковые литералы, может оставить недействительные процедуры. Наконец, данная форма более совместима со стандартом SQL и другими реализациями SQL.


Примечания

Дополнительную информацию о создании функций, которая также применима к процедурам, см. на справочной странице команды CREATE FUNCTION.

Чтобы выполнить процедуру, воспользуйтесь командой CALL.


Примеры

CREATE PROCEDURE insert_data(a integer, b integer)
LANGUAGE SQL
AS $$
INSERT INTO tbl VALUES (a);
INSERT INTO tbl VALUES (b);
$$;

или

CREATE PROCEDURE insert_data(a integer, b integer)
LANGUAGE SQL
BEGIN ATOMIC
  INSERT INTO tbl VALUES (a);
  INSERT INTO tbl VALUES (b);
END;

и вызов вроде такого:

CALL insert_data(1, 2);

Совместимость

Команда CREATE PROCEDURE определена в стандарте SQL. Ее реализацию в QHB можно использовать совместимым образом, но у нее есть множество расширений. Дополнительную информацию см. на справочной странице команды CREATE FUNCTION.

См. также

ALTER PROCEDURE, DROP PROCEDURE, CALL, CREATE FUNCTION