Каковы различия между «хранимыми процедурами» и «хранимыми функциями»?

36

Поэтому в комментарии к этому вопросу упоминается, что существует небольшая разница в «хранимых процедурах» и «хранимых функциях» в PostgreSQL.

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

Сам синтаксис кажется немного запутанным:

CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
    BEGIN
       [...]
    END;
$emp_stamp$ LANGUAGE plpgsql;

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
    FOR EACH ROW EXECUTE PROCEDURE emp_stamp();

Вы создаете, FUNCTIONно называете это PROCEDURE.

Так в чем же разница между этими двумя?

DrColossos
источник

Ответы:

43

Официально PostgreSQL имеет только «функции». Триггерные функции иногда называют «триггерными процедурами», но это использование не имеет определенного значения. Внутренне функции иногда называют процедурами, например, в системном каталоге pg_proc. Это пережиток PostQUEL. Любые функции, которые некоторые люди (возможно, имеющие опыт работы в разных системах баз данных) могут связывать с процедурами, например их актуальность для предотвращения SQL-инъекций или использования выходных параметров, также применяются к функциям, существующим в PostgreSQL.

Теперь, когда люди в сообществе PostgreSQL говорят о «хранимых процедурах» или «реальных хранимых процедурах», они часто имеют в виду гипотетическую особенность функционально-подобного объекта, который может запускать и останавливать транзакции в его теле, чего не могут делать текущие функции. делать. Использование термина «хранимая процедура» в этом контексте, по-видимому, аналогично другим продуктам баз данных. Посмотрите эту ветку списка рассылки для расплывчатой ​​идеи.

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

Питер Айзентраут
источник
14

В терминах DDL у Postgres нет процедурных объектов, только функции. Функции Postgres могут возвращать значение (я) или void, поэтому они играют роли как функций, так и процедур в других РСУБД. Слово «процедура» в create triggerссылке относится к функции.

В терминах документации Postgres «процедура» также является синонимом объекта базы данных, называемого функцией, например: « Процедура запуска создается с помощью команды CREATE FUNCTION ».

У «процедур» триггера есть определенные правила: они должны быть объявлены как функция без аргументов и возвращаемого типа триггера . Пример тут .

Джек Дуглас
источник
8

Термины «хранимая процедура» и «хранимая функция» используются в PostgreSQL взаимозаменяемо и обычно означают одно и то же. Другие базы данных могут различать процедуру и функцию (очень похоже на то, как VB различает подпрограммы и функции).

Пока функция в PostgreSQL возвращает что-то похожее на таблицу, вы можете использовать вывод этой функции, как если бы это была стандартная таблица. CREATE TRIGGERСинтаксис немного запутанным, но я подозреваю , что это может быть на месте до того , как стандарт ANSI был завершен. У меня есть только копия SQL: 2003, так что я не могу ничего сделать, кроме как размышлять, почему номенклатура странная.

TL; версия DR: с PostgreSQL «процедура» эквивалентна «функции».

Иеремия Пешка
источник
6

В MSSQL хранимая процедура - это предварительно скомпилированный набор команд sql.
Хранимая процедура:

 - может иметь много входных и выходных параметров
 - может использоваться для изменения таблиц / структур / данных базы данных
 - обычно не используются внутри операторов вставки / обновления / удаления / выбора
Пользовательские функции доступны в нескольких вариантах. В зависимости от типа написанной функции, функции:
  - может иметь несколько входных параметров, но возвращать только одно значение (т. е. конкатенация строк)
  - может принять набор в качестве входных данных, вернуть одно значение (т.е. dbo.FindLargestPig (ListOfPigs))
  - вернуть таблицу (т.е. выбрать * из dbo.ExplodeString («это список слов»))
  - может использоваться в операторах выбора / вставки / обновления / удаления
  - НЕ МОЖЕТ использоваться для изменения таблиц / структур / данных базы данных

datagod
источник
5

Короткий ответ - функция возвращает значение, а процедура - нет.

Это различие присутствовало в постоянных хранимых модулях (SQL / PSM), которые были предложены для SQL 1992. Я не знаю, был ли SQL / PSM когда-либо превращен в стандарты.

Майк Шеррилл 'Cat Recall'
источник
к 2003 году я верю
xenoterracide
Это звучит замечательно, как синтаксис для VB. Функция возвращает значение, а процедура - нет (поэтому, если бы у вас было возвращаемое значение в функции, она бы
взорвалась
@jcolebrand На самом деле, имена более очевидны в Паскале. Процедура не возвращает результат, в то время как функция делает. По историческим причинам VBA использует язык FORTRAN, который называет (называется?) Их SUBROUTINE & FUNCTION . В современных языках типа C есть только функции, но в типизированных языках есть возможность использования функций void, которые являются процедурами под другим именем. Популярная тенденция - просто использовать нормальные функции для всего и возвращать что-то, что можно игнорировать, если вы хотите.
Manngo
2

Сравнивая принятый ответ с абстрактного концептуального уровня, я понимаю разницу с точки зрения функциональности и ввода / вывода. Ниже я использовал sp и f для представления хранимой процедуры и функции соответственно.

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

    select * 
    from table 
    where col_a < (select col_A from f())
  2. вернуть значение: sp не возвращает значение автоматически, если вы не укажете тип возврата refcursor , откроете и вернете курсор; f возвращает результат в последнем операторе, в который вставлено предложение return, как предложение select .

  3. возвращать наборы результатов одного / нескольких: здесь наборы результатов относятся к списку результатов, которые могут различаться по формату, например, набор из одного целого числа, текстового массива и двух таблиц. sp может возвращать несколько наборов, пока вы указываете тип возвращаемого значения refcursor, открываете и возвращаете курсор. Однако f может возвращать только один тип набора.

Обычно хранимые процедуры используются для изменения данных или структуры базы данных, где возвращаемое значение не требуется, например, удаление, обновление, удаление и т. Д .; или ситуации, когда требуется несколько наборов результатов. Функция, с другой стороны, в основном выбирается для простых запросов.

Для более подробной информации относительно моего объяснения, пожалуйста, обратитесь к этой ссылке: Хранимые процедуры и функции в PostgreSQL

Фрэнк
источник