· Если компиляция прошла успешно, исполняемый код (p-код) будет сохранен в словаре базы данных, и функция может быть вызвана
· Если компиляция прошла успешно, и был сгенерирован p-код, хранимая функция может быть вызвана из любого инструмента, поддерживающего PL/SQL. Хранимая функция может быть вызвана, как часть выражения PL/SQL или из предложения SQL.
SQL> CREATE OR REPLACE FUNCTION emp_sal (v_job IN VARCHAR2)
2 RETURN NUMBER
3 IS
4 v_sal_inner emp.sal%TYPE;
5 BEGIN
6 SELECT sal INTO v_sal_inner FROM emp WHERE LOWER(job)=LOWER(v_job);
7 RETURN v_sal_inner;
8 END emp_sal;
9 /
Function created.
SQL> VARIABLE h_sal NUMBER
SQL> EXECUTE :h_sal := emp_sal('President')
PL/SQL procedure successfully completed.
SQL> PRINT h_sal
H_SAL
----------
5000
Хранимые функции могут быть вызваны, как часть выражения SQL, для выполнения сложных вычислений, увеличения производительности SQL запроса (ограничивая выборку строк с помощью хранимых функций, используемых в предложении WHERE, а не в приложении) или сложного манипулирования символьными данными (например, кодирование данных). Хранимые функции могут быть использованы везде, где могут быть использованы встроенные функции SQL:
· В списке выбора команды SELECT
· В предложениях WHERE, HAVING
· В предложениях ORDER BY, GROUP BY
· В предложении VALUES команды INSERT
· В предложении SET команды UPDATE
SQL> CREATE OR REPLACE FUNCTION pres_sal (v_sal IN NUMBER)
2 RETURN NUMBER
3 IS
4 v_sal_inner emp.sal%TYPE;
5 BEGIN
6 SELECT sal INTO v_sal_inner FROM emp WHERE LOWER(job)='president';
7 RETURN v_sal_inner*0.1+v_sal;
8 END pres_sal;
9 /
Function created.
SQL> SELECT ename, sal, pres_sal(sal) FROM emp WHERE LOWER(job)='clerk';
ENAME SAL PRES_SAL(SAL)
---------- ---------- -------------
SMITH 800 1300
ADAMS 1100 1600
JAMES 950 1450
MILLER 1300 1800
Однако хранимые функции, используемые в предложениях SQL, должны удовлетворять определенным условиям:
· В SQL могут использоваться только хранимые функции, а не процедуры
· Хранимая функция должна быть однострочной, а не групповой
· Хранимая функция может иметь только параметры IN. Параметры OUT и IN OUT не допускаются
· Типы данных параметров должны быть CHAR, DATE, NUMBER. Типы данных BOOLEAN, TABLE, RECORD не допускаются
· Тип возвращаемого значения должен быть внутренним типом данных сервера Oracle
· Способ передачи параметров может быть только позиционным
· Хранимая функция не может изменять данные таблиц базы данных. Команды манипулирования данными INSERT, UPDATE, DELETE не допускаются
· Вызов подпрограмм, нарушающих вышеизложенные условия, не допускается
Для удаления хранимой функции используется команда DDL DROP FUNCTION.
DROP FUNCTION имя_функции;
SQL> DROP FUNCTION emp_sal;
Function dropped.
SQL> DROP FUNCTION pres_sal;
Function dropped.
Хранимые процедуры так же, как и хранимые функции могут возвращать вычисленные значения в вызывающую среду. Поэтому необходимо достаточно ясно представлять себе различия между процедурой и функцией, чтобы выбрать правильную стратегию при планировании программной логики. Создавайте процедуру, чтобы сохранить последовательность действий для последующего использования и создавайте функцию, чтобы вычислить значение, которое должно быть возвращено в вызывающую среду. Процедура, содержащая один параметр OUT, легко может быть переписана в виде функции
Процедура |
Функция |
Вызывается в качестве целой команды PL/SQL |
Вызывается как часть выражения |
Может, но не обязана возвращать значение в вызывающую среду |
Обязана возвращать значение в вызывающую среду |
Не могут быть вызваны из предложений SQL |
Могут быть вызваны из предложений SQL |
Улучшение производительности приложения. SQL предложения, встречающиеся в хранимых подпрограммах, имеют идентичный синтаксис. Следовательно при повторном выполнении, уже разобранное SQL выражение будет найдено в разделяемой области SQL, что существенно сократит время отклика. Кроме того сами хранимые подпрограммы разбираются во время компиляции, а не выполнения. Это, также, сокращает время выполнения подпрограммы.
Улучшение поддержки приложений. Одна и та же подпрограмма может использоваться в разных приложениях, поэтому достаточно модифицировать эту программную единицу вместо того, чтобы исправлять все приложения, в которых она используется.
Безопасность и целостность данных. Чтобы разрешить пользователю изменять данные посредством подпрограммы, необходимо предоставить только привилегию на выполнение этой программной единицы. Это позволяет предотвратить несанкционированный прямой доступ к данным, минуя программную логику приложения. Кроме того, подпрограмма позволяет автоматически выполнять связанные действия по обновлению данных в одной транзакции, что предохраняет данные от нарушения целостности.
Для создания, выполнения, модификации и удаления хранимых программных единиц требуются соответствующие системные и объектные привилегии.
Чтобы пользователь мог создавать программные единицы в собственной схеме, необходима системная привилегия: Программные единицы в собственной схеме можно перекомпилировать, выполнить или удалить, для этого привилегии не нужны.
· CREATE (ANY) PROCEDURE – право создавать хранимые программные единицы в собственной (или любой) схеме
· ALTER ANY PROCEDURE – право перекомпилировать программные единицы в любой схеме
· DROP ANY PROCEDURE – право удалять программные единицы в любой схеме
· EXECUTE ANY PROCEDURE – право выполнять любые программные единицы
Пользователь, создавший подпрограмму, может предоставить кому-либо объектную привилегию на выполнение этой программной единицы.
· EXECUTE имя_подпрограммы
По умолчанию хранимые подпрограммы и SQL предложения, вызываемые из хранимой программной единицы, выполняются с привилегиями пользователя, который ее создал. По этой причине объектные привилегии на объекты, к которым обращается подпрограмма, не нужны, если объекты находятся в той же схеме, что и сама подпрограмма (владелец объектов всегда имеет привилегии на них). С одной стороны это хорошо, т.к. для манипулирования объектами через программную единицу требуется единственная привилегия на выполнение этой подпрограммы. С другой стороны, такие подпрограммы оказываются жестко привязанными к схеме, в которой они хранятся, что может вызвать определенные неудобства. Например, одна и та же таблица dept находится одновременно в двух схемах: scott и blake, а хранимая процедура create_dept создана в схеме scott:
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.