Spec-Zone .ru
спецификации, руководства, описания, API

13.1.12. CREATE PROCEDURE иCREATE FUNCTION Синтаксис

CREATE    [DEFINER = { user | CURRENT_USER }]    PROCEDURE sp_name ([proc_parameter[,...]])    [characteristic ...] routine_bodyCREATE    [DEFINER = { user | CURRENT_USER }]    FUNCTION sp_name ([func_parameter[,...]])    RETURNS type    [characteristic ...] routine_bodyproc_parameter:    [ IN | OUT | INOUT ] param_name typefunc_parameter:    param_name typetype:    Any valid MySQL data
        typecharacteristic:    COMMENT 'string'  | LANGUAGE SQL  | [NOT] DETERMINISTIC  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }  | SQL SECURITY { DEFINER | INVOKER }routine_body:    Valid SQL routine
        statement

Эти операторы создают сохраненные подпрограммы. По умолчанию подпрограмма связывается с базой данных значения по умолчанию. Чтобы связать подпрограмму явно с данной базой данных, определите имя как db_name.sp_name когда Вы создаете это.

CREATE FUNCTION оператор также используется в MySQL, чтобы поддерживать UDFs (определяемые пользователем функции). См. Раздел 22.3, "Добавляя Новые Функции к MySQL". UDF может быть расценен как внешняя сохраненная функция. Сохраненные функции совместно используют свое пространство имен с UDFs. См. Раздел 9.2.4, "Парсинг имени функции и Разрешение", для правил, описывающих, как сервер интерпретирует ссылки на различные виды функций.

Чтобы вызвать хранимую процедуру, используйте CALL оператор (см. Раздел 13.2.1,"CALL Синтаксис"). Чтобы вызвать сохраненную функцию, обратитесь к этому в выражении. Функция возвращает значение во время вычисления выражения.

CREATE PROCEDURE и CREATE FUNCTION потребуйте CREATE ROUTINE полномочие. Они могли бы также потребовать SUPER полномочие, в зависимости от DEFINER значение, как описано позже в этом разделе. Если двоичное журналирование включается, CREATE FUNCTION мог бы потребовать SUPER полномочие, как описано в Разделе 18.7, "Двоичное Журналирование Сохраненных Программ".

По умолчанию MySQL автоматически предоставляет ALTER ROUTINE и EXECUTE полномочия стандартному создателю. Это поведение может быть изменено, отключая automatic_sp_privileges системная переменная. См. Раздел 18.2.2, "Сохраненные Подпрограммы и MySQL Privileges".

DEFINER и SQL SECURITY пункты определяют контекст защиты, который будет использоваться, проверяя права доступа в стандартное время выполнения, как описано позже в этом разделе.

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

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

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

Каждый параметр IN параметр по умолчанию. Чтобы определить иначе для параметра, используйте ключевое слово OUT или INOUT перед названием параметра.

Отметить

Определение параметра как IN, OUT, или INOUT допустимо только для a PROCEDURE. Для a FUNCTION, параметры всегда расцениваются как IN параметры.

IN параметр передает значение в процедуру. Процедура могла бы изменить значение, но модификация не видима к вызывающей стороне, когда процедура возвращается. OUT параметр передает значение из процедуры назад к вызывающей стороне. Его начальное значение NULL в пределах процедуры, и ее значения видимо к вызывающей стороне, когда процедура возвращается. INOUT параметр инициализируется вызывающей стороной, может быть изменен процедурой, и любое изменение, произведенное процедурой, видимо к вызывающей стороне, когда процедура возвращается.

Для каждого OUT или INOUT параметр, передайте определяемую пользователем переменную в CALL оператор, который вызывает процедуру так, чтобы можно было получить ее значение, когда процедура возвращается. Если Вы вызываете процедуру изнутри другой хранимой процедуры или функции, можно также передать стандартный параметр или локальную стандартную переменную как IN или INOUT параметр.

На стандартные параметры нельзя сослаться в операторах, подготовленных в пределах подпрограммы; см. Раздел D.1, "Ограничения на Сохраненные Программы".

Следующий пример показывает простую хранимую процедуру, которая использует OUT параметр:

mysql> delimiter //mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)    -> BEGIN    ->   SELECT COUNT(*)
        INTO param1 FROM t;    -> END//Query OK, 0 rows affected (0.00 sec)mysql> delimiter ;mysql> CALL
        simpleproc(@a);Query OK, 0 rows affected (0.00 sec)mysql> SELECT
        @a;+------+| @a   |+------+| 3    |+------+1 row in set (0.00 sec)

Пример использует mysql клиент delimiter команда, чтобы изменить разделитель оператора от ; к // в то время как процедура определяется. Это включает ; разделитель, используемый в теле процедуры, которое пройдется к серверу вместо того, чтобы быть интерпретированным mysql непосредственно. См. Раздел 18.1, "Определяя Сохраненные Программы".

RETURNS пункт может быть определен только для a FUNCTION, для которого это обязательно. Это указывает на тип возврата функции, и тело функции должно содержать a RETURN value оператор. Если RETURN оператор возвращает значение различного типа, значение принуждается к надлежащему типу. Например, если функция определяет ENUM или SET значение в RETURNS пункт, но RETURN оператор возвращает целое число, значение, возвращенное из функции, является строкой для соответствия ENUM элемент набора SET элементы.

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

mysql> CREATE FUNCTION hello (s
        CHAR(20))mysql> RETURNS CHAR(50)
        DETERMINISTIC    -> RETURN CONCAT('Hello,
        ',s,'!');Query OK, 0 rows affected (0.00 sec)mysql> SELECT
        hello('world');+----------------+| hello('world') |+----------------+| Hello, world!  |+----------------+1 row in set (0.00 sec)

Типы параметра и функциональные типы возврата, как могут объявлять, используют любой допустимый тип данных. COLLATE атрибут может использоваться если предшествующийся CHARACTER SET атрибут.

routine_body состоит из допустимого оператора подпрограммы SQL. Это может быть простым оператором такой как SELECT или INSERT, или составной оператор, записанный, используя BEGIN и END. Составные операторы могут содержать объявления, циклы, и другие операторы управляющей структуры. Синтаксис для этих операторов описывается в Разделе 13.6, "MySQL Compound-Statement Syntax".

MySQL разрешает подпрограммам содержать операторы DDL, такой как CREATE и DROP. MySQL также разрешает хранимым процедурам (но не сохраненные функции) содержать операторы транзакции SQL такой как COMMIT. Сохраненные функции, возможно, не содержат операторы, которые выполняют явную или неявную фиксацию или откат. Поддержка этих операторов не требуется стандартом SQL, который утверждает, что каждый поставщик DBMS может решить, разрешить ли им.

Операторы, которые возвращают набор результатов, могут использоваться в пределах хранимой процедуры, но не в пределах сохраненной функции. Этот запрет включает SELECT операторы, которые не имеют INTO var_list пункт и другие операторы такой как SHOW, EXPLAIN, и CHECK TABLE. Для операторов, которые могут быть решены в функциональное время определения возвратить набор результатов, a Not allowed to return a result set from a function ошибка происходит (ER_SP_NO_RETSET). Для операторов, которые могут быть решены только во времени выполнения возвратить набор результатов, a PROCEDURE %s can't return a result set in the given context ошибка происходит (ER_SP_BADSELECT).

USE операторы в пределах сохраненных подпрограмм не разрешаются. Когда подпрограмма вызывается, неявное USE db_name выполняется (и отменяется, когда подпрограмма завершается). Причины подпрограмма, чтобы иметь данную базу данных значения по умолчанию, в то время как это выполняется. Ссылки на объекты в базах данных кроме стандартной базы данных значения по умолчанию должны быть квалифицированы с соответствующим именем базы данных.

Для дополнительной информации об операторах, которые не разрешаются в сохраненных подпрограммах, см. Раздел D.1, "Ограничения на Сохраненные Программы".

Для получения информации о вызове хранимых процедур изнутри программ, записанных на языке, у которого есть интерфейс MySQL, см. Раздел 13.2.1,"CALL Синтаксис".

MySQL хранит sql_mode системная переменная, устанавливающая в действительности, когда подпрограмма создается или изменяется, и всегда выполняет подпрограмму с этой установкой в силе, независимо от текущего режима SQL сервера, когда подпрограмма начинает выполняться.

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

COMMENT характеристика является расширением MySQL, и может использоваться, чтобы описать сохраненную подпрограмму. Эта информация выводится на экран SHOW CREATE PROCEDURE и SHOW CREATE FUNCTION операторы.

LANGUAGE характеристика указывает на язык, на котором пишется подпрограмма. Сервер игнорирует эту характеристику; только подпрограммы SQL поддерживаются.

Подпрограмму считают "детерминированной", если она всегда приводит к тому же самому результату для тех же самых входных параметров, и "не детерминированный" иначе. Если ни один DETERMINISTIC ни NOT DETERMINISTIC дается в стандартном определении, значение по умолчанию NOT DETERMINISTIC. Чтобы объявить, что функция детерминирована, следует определить DETERMINISTIC явно.

Оценка природы подпрограммы основана на "честности" создателя: MySQL не проверяет что объявленная подпрограмма DETERMINISTIC свободно от операторов, которые приводят к недетерминированным результатам. Однако, misdeclaring подпрограмма мог бы влиять на результаты или влиять на производительность. Объявление недетерминированной подпрограммы как DETERMINISTIC мог бы привести к неожиданным результатам, заставляя оптимизатор сделать неправильный выбор плана выполнения. Объявление детерминированной подпрограммы как NONDETERMINISTIC мог бы уменьшить производительность, заставляя доступную оптимизацию не использоваться.

Если двоичное журналирование включается, DETERMINISTIC характеристика влияет, который принимает стандартный MySQL определений. См. Раздел 18.7, "Двоичное Журналирование Сохраненных Программ".

Подпрограмма, которая содержит NOW() функция (или ее синонимы) или RAND() недетерминировано, но это могло бы все еще быть безопасно от репликации. Для NOW(), двоичный журнал включает метку времени и тиражируется правильно. RAND() также тиражируется правильно, пока это вызывают только единственным временем во время выполнения подпрограммы. (Можно рассмотреть стандартную метку времени выполнения и семя случайного числа как неявные вводы, которые идентичны на ведущем устройстве и ведомом устройстве.)

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

SQL SECURITY характеристика может быть DEFINER или INVOKER определить контекст защиты; то есть, выполняет ли подпрограмма использование полномочий учетной записи, названной в подпрограмме DEFINER пункт или пользователь, который вызывает это. У этой учетной записи должно быть разрешение, чтобы получить доступ к базе данных, с которой связывается подпрограмма. Значение по умолчанию DEFINER. Пользователь, который вызывает подпрограмму, должен иметь EXECUTE полномочие для этого, как должен DEFINER считайте, если подпрограмма выполняется в контексте защиты устройства определения.

DEFINER пункт определяет учетную запись MySQL, которая будет использоваться, проверяя права доступа в стандартное время выполнения для подпрограмм, которые имеют SQL SECURITY DEFINER характеристика.

Если a user значение дается для DEFINER пункт, это должна быть учетная запись MySQL, определенная как 'user_name'@'host_name' (тот же самый формат, используемый в GRANT оператор), CURRENT_USER, или CURRENT_USER(). Значение по умолчанию DEFINER значение является пользователем, который выполняется CREATE PROCEDURE или CREATE FUNCTION или оператор. Это - то же самое как определение DEFINER = CURRENT_USER явно.

Если Вы определяете DEFINER пункт, эти правила определяют допустимое DEFINER пользовательские значения:

Для получения дополнительной информации о сохраненной стандартной безопасности, см. Раздел 18.6, "Управление доступом для Сохраненных Программ и Представления".

В пределах сохраненной подпрограммы, которая определяется с помощью SQL SECURITY DEFINER характеристика, CURRENT_USER возвращает подпрограмму DEFINER значение. Для получения информации о пользователе, контролирующем в пределах сохраненных подпрограмм, см. Раздел 6.3.12, "основанный на SQL MySQL Account Activity Auditing".

Рассмотрите следующую процедуру, которая выводит на экран количество числа учетных записей MySQL, перечисленных в mysql.user таблица:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()BEGIN  SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;END;

Процедура присваивается a DEFINER учетная запись 'admin'@'localhost' независимо от того, какой пользователь определяет это. Это выполняется с полномочиями той учетной записи независимо от того, какой пользователь вызывает это (потому что характеристика безопасности значения по умолчанию DEFINER). Процедура успешно выполняется или перестала работать в зависимости от того, имеет ли invoker EXECUTE полномочие для этого и 'admin'@'localhost' имеет SELECT полномочие для mysql.user таблица.

Теперь предположите, что процедура определяется с помощью SQL SECURITY INVOKER характеристика:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()SQL SECURITY INVOKERBEGIN  SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;END;

У процедуры все еще есть a DEFINER из 'admin'@'localhost', но в этом случае, это выполняется с полномочиями пользователя вызова. Таким образом процедура успешно выполняется или перестала работать в зависимости от того, имеет ли invoker EXECUTE полномочие для этого и SELECT полномочие для mysql.user таблица.

Сервер обрабатывает тип данных стандартного параметра, локальная стандартная переменная, создаваемая с DECLARE, или функциональное возвращаемое значение следующим образом: