
- •Создание пакетов
- •3 Procedure reset_comm
- •4 (V_comm in number);
- •5 End comm_package;
- •2 Function validate_comm
- •V_mgr in emp.Mgr%type,
- •V_empno number;
- •Index by binary integer;
- •2 Emp_table emp_package.Emp_table type;
- •Index by binary_integer;
- •Into g_comm
- •Interest real; -- общая переменная
- •Interest number
- •Into interest --процедуры
- •V_message varchar2(50);
- •V_proc_name || ‘ end;’;
- •V_cursor integer;
- •V_return integer;
- •V_ename emp.Ename%type;
- •V_sal emp.Sal%type;
- •V_column_value varchar(30) ;
- •Var v_out1 varchar2(10);
- •Var v_out2 number;
- •Контрольные вопросы.
Какую работу нужно написать?
3 Procedure reset_comm
4 (V_comm in number);
5 End comm_package;
6 /
Примеры вызовов общедоступной переменной или процедуры.
SQL>EXECUTE comm_package.g_comm := 5
SQL>EXECUTE comm_package.reset_comm(8)
Если считать, что процедура создавалась в схеме scott, то вызов таков:
SQL>EXECUTE scott.comm_package.reset_comm(8)
А если она на удалённой БД со строкой связи my, то – такой:
SQL>EXECUTE comm_package.reset_comm.@my(8)
Создание тела пакета
В теле пакета определяются все общедоступные и частные процедуры и функции. Последовательность, в которой конструкции определяются в теле пакета, имеет значение; конструкция должна быть определена прежде, чем на нее можно будет ссылаться из другой конструкции. Синтаксис:
CREATE [OR REPLACE] PACKAGE BODY имя_пакета
{IS | AS}
[определения закрытых структур данных]
[объявления закрытых переменных,типов и объектов]
[полные определения курсоров пакета]
[полные определения функций и процедур пакета]
[BEGIN
[выполняемые операторы]
[EXCEPTION
обработка исключений] ]
END [имя_пакета];
Примечание. Выполняемые операторы междуBEGINиEXCEPTION(END) образуют одноразовую процедуру, автоматически запускаемую в момент первого вызова пакета и только в этот момент.
Пример.
SQL> CREATE OR REPLACE PACKAGE BODY comm_package IS
2 Function validate_comm
3 (v_comm IN NUMBER) RETURN BOOLEAN
4 IS
5 v_max_comm NUMBER;
6 BEGIN
7 SELECT MAX(comm)
8 INTO v_max_comm
9 FROM emp;
10 IF v_comm > v_max_comm THEN RETURN (FALSE);
11 ELSE RETURN(TRUE);
12 END IF;
13 END validate_comm;
14 PROCEDURE reset_comm
15 (v_comm IN NUMBER)
16 IS
17 v_valid BOOLEAN;
18 BEGIN
19 v_valid := validate_comm(v_comm) ;
20 IF v_valid = TRUE THEN
21 g_comm := v_comm; --ссылка на глоб.перем-ую
22 ELSE
23 RAISE_APPLICATION_ERROR
24 (-20210,'Invalid commission');
25 END IF;
26 END reset_comm;
27 END comm_package ;
28 /
Здесь validate_comm– это частная процедура, аreset_comm– общедоступная. При этом частная процедура вызывается без упоминания в спецификации пакета, но одна находится в теле пакета до того как будет вызвана. Переменнаяg_comm не описана в теле пакета, а является глобальной.
Указания по разработке пакетов:
Делайте пакеты как можно более универсальными, чтобы использовать их других приложениях. Не создавайте пакеты, дублирующие то, что уже сделано стандартными средствами Oracle.
Спецификации пакетов отражают структуру вашего приложения, поэтому определяйте их прежде, чем создавать тело каждого пакета.
Спецификация пакета должна содержать только те конструкции, которые должны быть видимы для пользователей пакета. Таким образом, другие разработчики не смогут неправильно использовать пакет, основывая свой код на несущественных деталях.
Для уменьшения объема перекомпиляции в случае изменения кода включайте в спецификацию пакета как можно меньше конструкций. Изменение в теле пакета не требуют перекомпиляции зависимых конструкций. Напротив, изменения в спецификации пакета требуют перекомпиляции каждой хранимой подпрограммы, которая обращается к пакету.
Данные объявленные в спецификации, либо объявленные в теле пакета, но вне процедур и функций пакета являются данными пакета. Область видимости этих данных охватывает весь сеанс и перекрывает границы транзакций, т.е. данные пакета являются глобальными для программ пользователя. Т.о. надо иметь в виду следующее:
Инструкции COMMITиROOLBACKне изменяют состояние переменных пакета.
Курсор объявленный в пакете имеет глобальную область видимости и остаётся открытым до окончания сеанса, если вы не закроете его явно, либо с использованием директивы SERIALLY_REUSABLE(описанной позже).
Примечание. Рекомендуется (в соответствии с объектно-ориентированным подходом), скрывать важные структуры данных в теле пакета, а пользователю предоставлять только методы (процедуры) работы с данными.
Обращение к глобальной переменной пакета.
Если вы ссылаетесь на переменную, курсор, константу или исключение внутрипакета, дополнять их имена именем пакета не требуется, но если вы ссылаетесь на переменную, курсор, константу или исключение извнешнегоокружения, необходимо квалифицировать их имена именем пакета. Например:
CREATE OR REPLACE PROCEDURE hire_emp
(v_ename IN emp.ename%TYPE,