MySQL хранимая процедура против функции, что я буду использовать, когда? - PullRequest
147 голосов
/ 19 сентября 2010

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

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

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

Ответы [ 5 ]

241 голосов
/ 22 ноября 2012

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

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

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

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

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

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

    • Указание параметра как IN, OUT или INOUT действительно только для ПРОЦЕДУРЫ.Для ФУНКЦИИ параметры всегда рассматриваются как параметры IN.

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

Чтобы определить хранимую процедуруили функцию, используйте 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)

Еще несколько интересных отличий между FUNCTION и STORED PROCEDURE:

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

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

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

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

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

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

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

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

92 голосов
/ 19 сентября 2010

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

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

49 голосов
/ 19 сентября 2010

Одно существенное отличие состоит в том, что вы можете включить функцию в свои запросы 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)
8 голосов
/ 19 сентября 2010

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

Процедура выполняется с использованием запроса CALL.

0 голосов
/ 14 августа 2018

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

...