Функции и процедуры в Oracle

Кто-нибудь может объяснить, в чем основное различие между функциями и процедурами в Oracle? Зачем мне использовать процедуры, если я могу все делать с функциями?

  1. Если я не могу вызвать процедуру в операторе sql, хорошо, я напишу функцию, выполняющую ту же работу.
  2. Процедуры не возвращают значения, хорошо, я верну только sql% rowcount или 1 (успех), 0 (исключение) после любой операции с dml
  3. И процедуры, и функции могут передавать переменные в вызывающую среду через параметры OUT / IN OUT.

Я слышал, что основная разница в производительности: «процедуры быстрее функций». Но без подробностей.

Заранее спасибо.


person Samir    schedule 21.08.2014    source источник
comment
возможный дубликат В чем разница между функцией и процедура в PL / SQL?   -  person Jon Heller    schedule 21.08.2014
comment
Это не ответ: функции возвращают значения, а процедуры - нет. Я прочитал почти все ответы, прежде чем размещать здесь. Спасибо   -  person Samir    schedule 21.08.2014
comment
№2 в вашем вопросе - одна из главных причин, по которой я не рекомендую использовать функции. Использование кодов возврата для скрытия значимой ошибки - ужасная практика.   -  person Allan    schedule 01.12.2014


Ответы (7)


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

Некоторые различия между функциями и процедурами

  1. Функция всегда возвращает значение с помощью оператора return, в то время как процедура может возвращать одно или несколько значений с помощью параметров или может не возвращать вообще. Хотя OUT параметры все еще могут использоваться в функциях, они нецелесообразны, а также нет случаев, когда можно было бы найти в этом необходимость. Использование параметра OUT ограничивает использование функции в операторе SQL.

  2. Функции могут использоваться в типичных операторах SQL, таких как SELECT, INSERT, UPDATE, DELETE, MERGE, а процедуры - нет.

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

  4. Oracle предоставляет возможность создания «функциональных индексов» для повышения производительности последующих Оператор SQL. Это применяется при выполнении функции для индексированного столбца в предложении where запроса.

Дополнительная информация о функциях и функциях. Процедуры здесь и здесь.

person Romo Daneghyan    schedule 21.08.2014
comment
В порядке. Если функция может делать все, что могут делать процедуры, зачем мне функции? :) Кстати, функция также может возвращать несколько значений через параметры OUT. - person Samir; 21.08.2014
comment
Я уже упоминал в ответе :) Вы можете использовать функцию в обычном SQL, поскольку вы не можете использовать процедуру в операторах SQL. Итак, в обычном SQL вам нужно использовать функции. Функции могут использоваться в операторе выбора, обновления или удаления, в то время как процедура не может. - person Romo Daneghyan; 21.08.2014
comment
Извините, я хотел сказать, зачем мне процедуры? :) - person Samir; 21.08.2014
comment
Извините, мне придется поправить вас там. Функция может возвращать только одно значение, но вы также можете использовать параметры OUT для возврата нескольких значений из функции, хотя вы не сможете использовать эту функцию из оператора SQL. Также не уверен, что вы имеете в виду под «хранимой процедурой» - это предварительно скомпилированный план выполнения, в то время как функции не являются, компиляция как процедур, так и функций выполняется одинаково. Кроме того, знаете ли вы, что можете создавать индексы на основе функций, но не можете создавать индексы на основе процедур? Вы говорите, что Разницы нет, а есть разница, разве это не противоречит? - person AnBisw; 07.01.2015

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

В очень редких случаях:

  • Аргумент процедуры IN OUT быстрее, чем возврат функции, если встраивание включено.
  • Аргумент процедуры IN OUT выполняется медленнее, чем возврат функции, когда встраивание отключено.

Тестовый код

--Run one of these to set optimization level:
--alter session set plsql_optimize_level=0;
--alter session set plsql_optimize_level=1;
--alter session set plsql_optimize_level=2;
--alter session set plsql_optimize_level=3;

--Run this to compare times.  Move the comment to enable the procedure or the function.
declare
    v_result varchar2(4000);

    procedure test_procedure(p_result in out varchar2) is
    begin
        p_result := '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
    end;

    function test_function return varchar2 is
    begin
        return '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
    end;
begin
    for i in 1 .. 10000000 loop
        --Comment out one of these lines to change the test.
        --test_procedure(v_result);
        v_result := test_function;
    end loop;
end;
/

Результаты

Inlining enabled:  PLSQL_OPTIMIZE_LEVEL = 2 (default) or 3
Function  run time in seconds: 2.839, 2.933, 2.979
Procedure run time in seconds: 1.685, 1.700, 1.762

Inlining disabled: PLSQL_OPTIMIZE_LEVEL = 0 or 1
Function  run time in seconds:  5.164, 4.967, 5.632
Procedure run time in seconds: 6.1, 6.006, 6.037

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

Почему разница не имеет значения

Не смотрите на приведенный выше тест и не думайте, что «процедура выполняется в два раза быстрее, чем функция!». Да, накладные расходы функции почти вдвое больше, чем накладные расходы процедуры. Но в любом случае накладные расходы несущественно малы.

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

person Jon Heller    schedule 01.12.2014

С изменением состояния и без изменения состояния

Помимо ответа Ромо Данегяна, я всегда рассматривал разницу в их поведении в состоянии программы. То есть концептуально,

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

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

Конечно, похоже, что в Oracle, как и во многих других языках, это не применяется и не применяется, так что, возможно, это только я.

person typoerrpr    schedule 17.08.2016

  1. Процедура может возвращать или не возвращать значение, но функции возвращают значение.

  2. Процедура использует параметр returnvalue, но функция returnstatment предоставляет.

  3. процедура использовала манипулирование данными, но функция использовала вычисление данных.
  4. время выполнения процедуры не использует оператор выбора, а использует оператор выбора функции. Это основные отличия.
person dinesh    schedule 23.10.2015

Это отличный вопрос, и, насколько я могу судить, на него нет ответа. Вопрос не в том, «В чем разница между функцией и процедурой?» Скорее, это «Зачем мне вообще использовать процедуру, если я могу сделать то же самое с функцией?»

Я думаю, что настоящий ответ - «Это просто соглашение». И поскольку это соглашение, это то, к чему привыкли и ожидают другие разработчики, поэтому вы должны следовать соглашению. Но нет функциональной причины писать подпрограмму как процедуру над функцией. Единственное исключение может быть при наличии нескольких OUT параметров.

В его 6-м издании Oracle PL / SQL Programming , Стивен Фейерштейн рекомендует зарезервировать параметры OUT и IN OUT для процедур и возвращать информацию только в функциях через предложение RETURN (стр. 613). Но опять же, причина этого - условность. Разработчики не ожидают, что функции будут иметь OUT параметров.

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

person Webucator    schedule 19.07.2019

я думаю, что основная разница в следующем:

Функции не могут содержать DML Statemnt, тогда как процедуры могут. например, как "Обновить" и "Вставить".

если я ошибаюсь, поправьте меня

person shalini    schedule 18.12.2015
comment
В Oracle функция может содержать оператор DML. - person Jon Heller; 18.12.2015

Насколько я знаю, процедура Store компилируется один раз и может вызываться снова и снова без повторной компиляции. Но функция компилируется каждый раз при вызове. Итак, процедура Store улучшает производительность, чем функция.

person Anh Tuấn    schedule 01.12.2014
comment
Это миф, по крайней мере, для Oracle. Я никогда не видел надежного источника или тестового примера, демонстрирующего это. - person Jon Heller; 01.12.2014
comment
Совершенно неверно. Компиляция работает одинаково для процедур, функций, пакетов и триггеров (в Oracle). - person AnBisw; 07.01.2015