- •Создание пакетов
- •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;
- •Контрольные вопросы.
Index by binary_integer;
TYPE realtabtyp IS TABLE OF REAL
INDEX BY BINARY_INTEGER;
hiredate_tab datetabtyp;
sal_tab realtabtyp ;
indx ВINARY_INTEGER;
BEGIN
indx := 50;
initialize(hiredate_tab,indx); --вызов 1-го варианта
initialize(sal_tab,indx); --вызов 2-го варианта
. . .
END;
Предварительное объявление.
В PL/SQL, программа (как и любой идентификатор) должна быть описана до того, как на неё сошлются. Но если программы вызывают друг друга (взаимная рекурсия), то перестановки описаний недостаточно – требуется предварительное объявление (forwarddeclaration).
Предварительное объявление состоит из заголовка программы, располагающегося до ключевого слова IS(илиAS) и заканчивающегося точкой с запятой. Пример:
. . .
PROCEDURE calc_rating(...); -- предварительное
-- объявление
. . .
PROCEDURE award_bonus(...)IS -- объявление подпрограмм
BEGIN -- в алфавитном порядке
calc_rating(. . .);
. . .
END;
PROCEDURE calc_rating(. . .) IS
BEGIN
award_bonus(. . .);
. . .
END;
Правила предварительного объявления:
Список формальных параметров должен присутствовать как в предварительном объявлении, так и в теле подпрограммы.
Тело подпрограммы может появиться в любом месте после предварительного объявления, но они должны быть в пределах одной и той же программной единицы.
Предварительное объявление обычно используется в следующих целях:
Для определения программ в алфавитном или логическом порядке
Для определения взаимно рекурсивныхподпрограмм
Для объединения подпрограмм в пакет
Обычно предварительные объявления позволяют объединять взаимосвязанные программы в пакеты. Спецификации программ становятся частью спецификации пакета, а тела программ - частью тела пакета, где они невидимы для приложений. Таким образом, пакеты помогают скрыть детали реализации.
Одноразовые процедуры
Такая процедура не имеет имени и выполняется только один раз, когда пакет впервые вызывается во время пользовательского сеанса.
Примечание: автоматическую одноразовую процедуру можно использовать для инициализации общедоступных или частных переменных, если вычисления слишком сложны, чтобы включать их в объявление переменной. Но в этом случаене инициализируйте переменную при объявлении, т.к. это значение будет сброшено одноразовой процедурой.
Пример.
CREATE OR REPLACE PACKAGE BODY comm_package IS
FUNCTION validate_comm
. . .
END validate_comm;
. . .
END reset_comm;
-- Автоматическая одноразовая процедура
-- (устанавливает глобальную переменную g_comm)
BEGIN
SELECT AVG(comm)
Into g_comm
FROM emp;
END comm_package;
Побочные эффекты.
Чтобы сервер Oracleмог выполнить SQL команду, которая вызывает хранимую функцию, он должен знать, что функция не имеет побочных эффектов. Побочные эффекты - это изменения в таблицах базы данных или общедоступных пакетных переменных (объявленных в спецификации пакета). Побочные эффекты могут замедлить выполнение запроса, привести к появлению результатов, зависимых от последовательности выполнения подпрограмм (и, следовательно, промежуточных), а также потребовать того, чтобы переменные, в которых хранится состояние пакета, сохранялись от сеанса к сеансу (что недопустимо). Поэтому к хранимым функциям, вызываемым из SQL-выражений, применяются следующие ограничения:
Функция не может модифицировать таблицы базы; следовательно, она не может выполнять операции INSERT, UPDATE и DELETE.
Функции, которые читают или изменяют значения пакетных переменных, не могут выполняться дистанционно или в параллельном режиме.
Изменять значения пакетных переменных могут только функции, вызываемые из предложения SELECT, VALUES или SET.
Функция не может вызывать никакую другую подпрограмму, нарушающую одно из вышеуказанных правил. Кроме того, функция не может обращаться к представлению, нарушающему какое-либо из этих правил.
Ограничение функции в правах обращения.
Такое ограничение задаётся директивой компилятора
PRAGMA RESTRICT_REFERENCES(имя_функции |DEFAULT,
список_ограничений );
Указание DEFAULTговорит о том, что ограничения относятся ко всем функциям пакета.
В списке ограничений может быть один или несколько следующих указаний (которые иногда называются уровнями чистоты функции):
WNDS - Сокращение от "WritesNoDatabaseState", т.е. функция не может изменять таблицы базы данных.
RNDS- Сокращение от "ReadNoDatabaseState", т.е. функция не может запрашивать таблицы базы данных.
WNPS- Сокращение от "WritesNoPackageState", т.е. функция не может изменять значения пакетных переменных.
RNPS- Сокращение от "ReadNoPackageState", т.е. функция не может обращаться к общедоступным пакетным переменным.
TRUST – (доверять), указанные для пакета ограничения не вступают в силу для данной функции и компилятору приходится «верить», что побочные эффекты функции – правильные.
Попытка скомпилировать тело функции, нарушающее указание, директивы PRAGMAприведет к ошибке компиляции.
В случае автономных функций сервер Oracleможет обеспечить соблюдение этого ограничения путем проверки тела функции. Но тело пакетной функции скрыто; видима только спецификация. Следовательно, для пакетных функций использование директивы PRAGMA обязательно.
Если пакет включает несколько одноименных функций, указание компилятору в директиве PRAGMA относится к последней функции.
Пример. Создаём функцию COMPOUND в пакете FINANCE. Функция будет вызываться из SQL-команд в удаленных базах данных. Поскольку удаленные функции не могут ни читать, ни изменять значения пакетных переменных. Они также не должны изменять таблицы базы данных, т.к. вызываются из SQL-команды. Следовательно, необходимо указать ограничения RNPS, WNPS и WNDS.
CREATE OR REPLACE PACKAGE finance -- спецификация
AS -- пакета