MySQL зберігається процедура проти функції, яку я б використовував коли?


160

Я дивлюся на збережені MySQL процедури та функції. Яка реальна різниця?

Вони, схоже, схожі, але функція має більше обмежень.

Я, мабуть, помиляюся, але здається, що збережена процедура може зробити все, і більше збережена функція може. Чому / коли я використовую процедуру проти функції?

Відповіді:


101

Ви не можете змішувати збережені процедури зі звичайним SQL, хоча і зі збереженою функцією ви можете.

Наприклад SELECT get_foo(myColumn) FROM mytable, не вірно, якщо get_foo()це процедура, але ви можете це зробити, якщо get_foo()це функція. Ціна полягає в тому, що функції мають більше обмежень, ніж процедура.


18
Які обмеження мають функції?
Fantius

11
О, я знайшов тут добру інформацію: dev.mysql.com/doc/refman/5.0/uk/…
Fantius

262

Найбільш загальна відмінність між процедурами та функціями полягає в тому, що вони викликаються по-різному та з різною метою:

  1. Процедура не повертає значення. Замість цього на нього викликається оператор CALL для виконання такої операції, як зміна таблиці або обробка отриманих записів.
  2. Функція викликається в виразі і повертає одне значення безпосередньо абоненту, який буде використаний у виразі.
  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) можуть використовуватися в збережених процедурах, але не зберігаються функціях або тригерах. Таким чином, збережені функції та тригери не можуть використовувати Dynamic SQL (де ви конструюєте оператори як рядки та виконуєте їх виконання). (Динамічний SQL у збережених процедурах MySQL)

Ще кілька цікавих відмінностей між функцією ФУНКЦІЇ та ЗБЕРІГАНОЮ:

  1. ( Цей пункт скопійовано з блогу . ) Збережена процедура є попередньо складеним планом виконання там, де функцій немає. Функція розбирається та компілюється під час виконання. Зберігаються процедури, зберігаються як псевдо-код у базі даних, тобто у складеній формі.

  2. ( Я не впевнений в цьому. )
    Збережена процедура має захист і зменшує мережевий трафік, а також ми можемо викликати збережену процедуру в будь-яку ні. заявок одночасно. довідник

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

  4. Функції не можуть впливати на стан бази даних (Заяви, які роблять явну чи неявну фіксацію чи відкат, заборонені у функціонуванні). Зберігаються процедури можуть впливати на стан бази даних, використовуючи посилання комісій тощо
    . J.1. Обмеження щодо збережених рутин і тригерів

  5. Функції не можуть використовувати оператори FLUSH, тоді як зберігаються процедури.

  6. Збережені функції не можуть бути рекурсивними, тоді як зберігаються процедури. Примітка: Рекурсивні збережені процедури відключені за замовчуванням, але їх можна активувати на сервері, встановивши систему змінної max_sp_recursion_depth на ненульове значення. Для отримання додаткової інформації див. Розділ 5.2.3, “Змінні системи” .

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

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


2
@GrijeshChauhan, Що ти маєш на увазі, коли ти кажеш, що "Функція розібрана і складена під час виконання" ?
Pacerier

@Pacerier означає, що функції в MySQL є чимось на зразок скриптів, які компілюються та виконуються на льоту. Я скопіював це з якоїсь публікації в блозі , але не виконав жодної практичної перевірки такої поведінки.
Гріеш Чаухан

У процедурах ви можете передавати змінну як параметр, а потім викликати її з оператором select
LTroya

1
Пункт №4 у нижньому розділі цієї відповіді, я думаю, суть різниці між процедурами та функціями. процедури можуть змінювати базу даних, функції не можуть. всі інші відмінності полягають у тому, щоб ефективніше служити цій меті.
Вудро Барлоу

51

Одна істотна відмінність полягає в тому, що ви можете включати функцію у свої 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)

1
Ваша функція має дві віддачі ? Я маю на увазі, що це за рядок? RETURNS CHAR(50) DETERMINISTIC?
Мартін AJ

У RETURNS CHAR(50)стані , який тип даних буде повернуто. Це RETURN CONCAT(...дані, які повертаються. Обидва потрібні. DETERMINISTICНеобхідно , щоб стан , що основні дані не будуть змінені.
lemming622

8

Збережена функція може використовуватися в запиті. Потім ви можете застосувати його до кожного рядка або в пункті WHERE.

Процедура виконується за допомогою запиту CALL.


0

Збережену процедуру можна назвати рекурсивно, але збережена функція не може

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.