Функции и процедуры в Oracle
может ли кто-нибудь объяснить, что является основным различием между функциями и процедурами в Oracle? Почему я должен использовать процедуры, если я могу делать все с помощью функций?
- Если я не могу вызывать процедуру в инструкции sql, нормально, я напишу функцию для выполнения той же работы.
- Процедуры не возвращают значения, нормально, я верну только sql% rowcount или 1 (успех), 0 (исключение) после любой операции dml
- Обе процедуры и функции могут передавать переменные в вызывающую среду через параметры OUT/IN OUT
Я слышал, что основное отличие в производительности: "процедуры быстрее, чем функции". Но без каких-либо подробностей.
Спасибо заранее.
Ответы
Ответ 1
Разница - функция должна возвращать значение по умолчанию (любого типа) по определению по умолчанию, тогда как в случае процедуры вам нужно использовать параметры, такие как OUT
или IN OUT
для получения результатов. Вы можете использовать функцию в обычном SQL
, где вы не можете использовать процедуру в операторах SQL
.
Некоторые различия между функциями и процедурами
-
Функция всегда возвращает значение с помощью оператора return, в то время как процедура может возвращать одно или несколько значений через параметры или может вообще не возвращаться. Хотя параметры OUT
все еще могут использоваться в функциях, они не являются нецелесообразно, чтобы не было случаев, когда можно было бы это сделать. Использование параметра OUT
ограничивает использование функции в SQL-заявлении.
-
Функции могут использоваться в типичных операторах SQL, таких как SELECT
, INSERT
, UPDATE
, DELETE
, MERGE
, в то время как процедуры не могут.
-
Функции обычно используются для вычислений, где, как правило, обычно используются для выполнения бизнес-логики.
-
Oracle обеспечивает предоставление "индексов, основанных на функциях", чтобы повысить производительность последующего оператора SQL. Это применимо при выполнении функции в индексированном столбце в where where запроса запроса.
Дополнительная информация о функциях Vs. Процедуры здесь и здесь.
Ответ 2
Практически не существует разницы в производительности между процедурами и функциями.
В нескольких крайне редких случаях:
- Аргумент
IN OUT
процедуры быстрее, чем функция return, когда включена inlining.
- Аргумент
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 в пакетах. Если программа вызывает функцию или процедуру десять миллионов раз в секунду, эта программа имеет серьезные проблемы с дизайном.
Ответ 3
Изменение состояния по сравнению с изменением состояния
Помимо ответа Ромо Данегяна, я всегда рассматривал разницу как их поведение в состоянии программы. То есть концептуально
- Процедуры могут изменять некоторые состояния, либо параметров, либо среды (например, данные в таблицах и т.д.).
- Функции не изменяют состояние, и вы ожидаете, что вызов определенной функции не изменит какие-либо данные/состояние. (Т.е. концепция, лежащая в основе функционального программирования)
Т.е., если бы вы вызвали функцию с именем generateId(...)
, вы бы ожидали, что она только выполнит некоторые вычисления и вернет значение. Но, вызывая процедуру generateId...
, вы можете ожидать, что он изменит значения в некоторых таблицах.
Конечно, похоже, что в Oracle, как и во многих языках, это не применяется и не применяется, так что, возможно, это только я.
Ответ 4
-
Процедура может вернуть или не вернуть значение, но возвращает возвращаемое значение.
-
процедура использует параметр returnvalue, но возвращает функцию returnstatment.
- используется процедура манипуляции данными, но функция использует вычисления данных.
- время выполнения процедуры не использует оператор select, а оператор use select select. Это большая разница.
Ответ 5
Это отличный вопрос, и, насколько я могу судить, на самом деле не было ответа. Вопрос не в том, "Какая разница между функцией и процедурой?" Скорее, это "Зачем мне когда-либо использовать процедуру, когда я могу сделать то же самое с функцией?"
Я думаю, что реальный ответ: "Это просто соглашение". И в соответствии с соглашением, это то, к чему привыкли и ожидают другие разработчики, поэтому вы должны следовать соглашению. Но нет функциональной причины писать подпрограмму как процедуру над функцией. Единственным исключением может быть наличие нескольких параметров OUT
.
В своем 6-м издании Oracle PL/SQL Programming Стивен Фейерштайн рекомендует резервировать параметры OUT
и IN OUT
для процедур и возвращать информацию в функции только через предложение RETURN (стр. 613). Но опять же, причина этого в соглашении. Разработчики не ожидают, что функции будут иметь параметры OUT
.
Я написал здесь длинный пост, утверждая, что вы должны использовать процедуру, только когда функция не выполняет свою работу. Я лично предпочитаю функции и желаю, чтобы соглашение использовало функции по умолчанию, но я думаю, что лучше принять то, что я не могу изменить, и поклониться фактическому соглашению, а не тому, которое я бы хотел.
Ответ 6
Я думаю, что основное отличие:
Функции не могут содержать DML Statemnt, в то время как процедуры могут.
например, Update и Insert.
Если я ошибаюсь, верьте мне
Ответ 7
Как я знаю, процедура Store скомпилирована один раз и может быть вызвана снова и снова без компиляции. Но функция скомпилируется каждый раз. Таким образом, процедура Store улучшает производительность, чем функцию.