MySQL хранимая процедура vs функция, которую я бы использовал, когда?

Я смотрю на хранимые процедуры и функции MySQL. В чем реальная разница?

Они кажутся похожими, но функция имеет больше ограничений.

Я, вероятно, ошибаюсь,но, похоже, хранимая процедура может делать все и больше, чем хранимая функция. Почему / когда я буду использовать процедуру против функции?

5 ответов


вы не можете смешивать хранимые процедуры с обычным SQL, в то время как с сохраненной функцией вы можете.

например SELECT get_foo(myColumn) FROM mytable недопустимо, если get_foo() - это процедура, но вы можете сделать это, если get_foo() функция. Цена заключается в том, что функции имеют больше ограничений, чем процедура.


наиболее общее различие между процедурами и функциями состоит в том, что они вызываются по-разному и для разных целей:

  1. процедура не возвращает значение. Вместо этого он вызывается с помощью оператора CALL для выполнения такой операции, как изменение таблицы или обработка полученных записей.
  2. функция вызывается в выражении и возвращает одно значение непосредственно вызывающему объекту для использования в выражение.
  3. вы не можете вызвать функцию с оператором вызова, а также не можете вызвать процедуру в выражении.

синтаксис для рутинного создания несколько отличается для процедур и функций:

  1. параметры процедуры можно определить как вход-только, выход-только,или оба. Это означает, что процедура может передавать значения обратно с помощью выходных параметров. Эти значения можно найти в инструкции по оператор Call. Функции имеют только входные параметры. В результате, хотя и процедуры, и функции могут иметь параметры, объявление параметров процедуры отличается от объявления для функций.
  2. функции возвращают значение, поэтому в определении функции должно быть предложение RETURNS для указания типа данных возвращаемого значения. Кроме того, в теле функции должен быть хотя бы один оператор RETURN для возврата значения вызывающему объекту. RETURNS и RETURN не отображаются в определение процедуры.

    • чтобы вызвать хранимую процедуру, используйте CALL statement. Чтобы вызвать хранимую функцию, обратитесь к ней в выражении. Функция возвращает значение во время вычисления выражения.

    • процедура вызывается с помощью оператора CALL и может передавать значения только с помощью выходных переменных. Функция может вызываться изнутри оператора так же, как и любая другая функция (то есть путем вызова имени функции), и может возвращать скалярное значение.

    • указание параметра как IN, OUT или INOUT допустимо только для процедуры. Для функции параметры всегда рассматриваются как In parameters.

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

В определите хранимую процедуру или функцию, используйте CREATE PROCEDURE или CREATE FUNCTION соответственно:

CREATE PROCEDURE proc_name ([parameters])
 [characteristics]
 routine_body


CREATE FUNCTION func_name ([parameters])
 RETURNS data_type       // diffrent
 [characteristics]
 routine_body

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

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

хранимые процедуры и функции не имеют общего пространства имен. в базе данных можно иметь процедуру и функцию с одинаковым именем.

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

подготовленные операторы SQL (PREPARE, EXECUTE, DEALLOCATE PREPARE) могут использоваться в хранимых процедурах, но не в хранимых функциях или триггерах. Таким образом, хранимые функции и триггеры не могут использовать динамический SQL (где вы строите операторы в виде строк, а затем выполняете их). (динамический SQL в MySQL хранятся подпрограммы)

некоторые более интересные различия между функцией и сохраненной Процедура:

  1. (этот пункт скопировано с блога.) Хранимая процедура-это скомпилированный план выполнения, где в качестве функции нет. Функция проанализирована и скомпилирована во время выполнения. Хранимые процедуры, хранящиеся в виде псевдокода в базе данных, т. е. скомпилированной форме.

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

  3. функции нормально использованы для вычислений где как процедур обычно используются для выполнения бизнес-логики.

  4. функции не могут влиять на состояние базы данных (Операторы, которые делают явную или неявную фиксацию или откат, запрещены в функции) Поскольку Хранимые процедуры могут влиять на состояние базы данных с помощью commit etc.
    refrence: Ж. 1. Ограничения на хранимые процедуры и триггеры

  5. функции не могут использовать FLUSH операторы, тогда как хранимые процедуры могут делать.

  6. сохраненные функции не могут быть рекурсивными, тогда как хранимые процедуры могут быть. Примечание: рекурсивные хранимые процедуры отключены по умолчанию, но могут быть включены на сервере, установив системную переменную max_sp_recursion_depth сервера ненулевое значение. См.5.2.3, "Системные Переменные", для получения дополнительной информации.

  7. в хранимой функции или триггере не разрешается изменять таблицу, которая уже используется (для чтения или записи) оператором, который вызвал функцию или триггер. Хороший Пример:Как обновить ту же таблицу при удалении в MYSQL?

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


одно существенное различие заключается в том, что вы можете включить функции в ваших SQL-запросах, но хранимых процедур можно вызвать только с помощью CALL о себе:

UDF пример:

CREATE FUNCTION hello (s CHAR(20))
   RETURNS CHAR(50) DETERMINISTIC
   RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)

CREATE TABLE names (id int, name varchar(20));
INSERT INTO names VALUES (1, 'Bob');
INSERT INTO names VALUES (2, 'John');
INSERT INTO names VALUES (3, 'Paul');

SELECT hello(name) FROM names;
+--------------+
| hello(name)  |
+--------------+
| Hello, Bob!  |
| Hello, John! |
| Hello, Paul! |
+--------------+
3 rows in set (0.00 sec)

Sproc Пример:

delimiter //

CREATE PROCEDURE simpleproc (IN s CHAR(100))
BEGIN
   SELECT CONCAT('Hello, ', s, '!');
END//
Query OK, 0 rows affected (0.00 sec)

delimiter ;

CALL simpleproc('World');
+---------------------------+
| CONCAT('Hello, ', s, '!') |
+---------------------------+
| Hello, World!             |
+---------------------------+
1 row in set (0.00 sec)

хранимая функция может использоваться в запросе. Затем вы можете применить его к каждой строке или в предложении WHERE.

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


хранимая процедура может вызываться рекурсивно, но хранимая функция не может