Теперь возьмем ситуацию, когда нам нужно добавить в пакет функцию умножающую два числа. Определенную вот так:
-- FUNCTION Mul_Two_Num -- CREATE OR REPLACE FUNCTION Mul_Two_Num(A IN NUMBER, B IN NUMBER) RETURN NUMBER IS BEGIN RETURN (A * B); END Mul_Two_Num;
Как это сделать? Достаточно просто сначала добавить ее описание в заголовке модуля:
-- НАШ ПЕРВЫЙ ПАКЕТ -- CREATE OR REPLACE PACKAGE test_pkg IS PROCEDURE Out_Screen(TOSC IN VARCHAR2); FUNCTION Add_Two_Num(A IN NUMBER, B IN NUMBER) RETURN NUMBER; FUNCTION Min_Two_Num(A IN NUMBER, B IN NUMBER) RETURN NUMBER; FUNCTION Mul_Two_Num(A IN NUMBER, B IN NUMBER) RETURN NUMBER; FUNCTION FACTORIAL(NUM IN NUMBER) RETURN NUMBER; END test_pkg; /
Компилируем и ждем результат:
SQL> CREATE OR REPLACE PACKAGE test_pkg IS 2 3 PROCEDURE Out_Screen(TOSC IN VARCHAR2); 4 5 FUNCTION Add_Two_Num(A IN NUMBER, B IN NUMBER) RETURN NUMBER; 6 7 FUNCTION Min_Two_Num(A IN NUMBER, B IN NUMBER) RETURN NUMBER; 8 9 FUNCTION Mul_Two_Num(A IN NUMBER, B IN NUMBER) RETURN NUMBER; 10 11 FUNCTION FACTORIAL(NUM IN NUMBER) RETURN NUMBER; 12 13 END test_pkg; 14 / Пакет создан.
Теперь давайте посмотрим, что же происходит с телом пакета. Дадим вот такой запрос к представлению USER_OBJECTS:
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS FROM USER_OBJECTS WHERE OBJECT_TYPE = 'PACKAGE BODY' /
Получаем:
SQL> SELECT OBJECT_NAME, OBJECT_TYPE, STATUS 2 FROM USER_OBJECTS 3 WHERE OBJECT_TYPE = 'PACKAGE BODY' 4 / OBJECT_NAME OBJECT_TYPE STATUS -------------------------- ------------------ ------- TEST_PKG PACKAGE BODY INVALID
Оп! А, тело теперь недействительно! Исправляем ситуацию:
-- PACKAGE BODY test_pkg -- CREATE OR REPLACE PACKAGE BODY test_pkg IS . . . -- FUNCTION Mul_Two_Num -- FUNCTION Mul_Two_Num(A IN NUMBER, B IN NUMBER) RETURN NUMBER IS BEGIN RETURN (A * B); END Mul_Two_Num; . . . END test_pkg; /
Добавляем функцию Mul_Two_Num к телу пакета и компилируем:
SQL> -- PACKAGE BODY test_pkg -- ************** SQL> CREATE OR REPLACE PACKAGE BODY test_pkg IS 2 . . . 33 34 -- FUNCTION Mul_Two_Num -- **************************************** 35 FUNCTION Mul_Two_Num(A IN NUMBER, B IN NUMBER) RETURN NUMBER 36 IS 37 38 BEGIN 39 40 RETURN (A * B); 41 42 END Mul_Two_Num; . . . 58 59 END test_pkg; 60 / Тело пакета создано.
Вот и все. Привожу текст в сокращенном виде дабы не занимать, лишнее место на Web - сервере. :) Вы можете проделать то же используя текст предыдущего шага. Главное не забывайте при изменении заголовка, если есть тело пакета хотя бы просто перекомпилировать его. В том случае, если вы добавили в заголовок не процедуру или функцию, а скажем переменную или курсор. Любое изменение заголовка делает тело пакет недействительным (invalid)! Просто перекомпилировать пакет можно так:
ALTER PACKAGE test_pkg COMPILE /
Получим:
SQL> ALTER PACKAGE test_pkg COMPILE 2 / Пакет изменен.
Посмотрим еще раз на состояние тела пакета:
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS FROM USER_OBJECTS WHERE OBJECT_TYPE = 'PACKAGE BODY' /
Получаем:
SQL> SELECT OBJECT_NAME, OBJECT_TYPE, STATUS 2 FROM USER_OBJECTS 3 WHERE OBJECT_TYPE = 'PACKAGE BODY' 4 / OBJECT_NAME OBJECT_TYPE STATUS -------------------------- ------------------ ------- TEST_PKG PACKAGE BODY VALID
Вот собственно все и получилось! Попробуем, как себя чувствует новоиспеченная функция в пакете:
SET SERVEROUTPUT ON DECLARE BEGIN test_pkg.Out_Screen(TO_CHAR(test_pkg.Min_Two_Num(10,4))); test_pkg.Out_Screen(TO_CHAR(test_pkg.Add_Two_Num(5,2))); test_pkg.Out_Screen(TO_CHAR(test_pkg.Add_Two_Num(test_pkg.FACTORIAL(5),4))); test_pkg.Out_Screen(TO_CHAR(test_pkg.Mul_Two_Num(2,2))); END; /
Получаем:
SQL> SET SERVEROUTPUT ON SQL> SQL> DECLARE 2 3 BEGIN 4 5 test_pkg.Out_Screen(TO_CHAR(test_pkg.Min_Two_Num(10,4))); 6 test_pkg.Out_Screen(TO_CHAR(test_pkg.Add_Two_Num(5,2))); 7 test_pkg.Out_Screen(TO_CHAR(test_pkg.Add_Two_Num(test_pkg.FACTORIAL(5),4))); 8 test_pkg.Out_Screen(TO_CHAR(test_pkg.Mul_Two_Num(2,2))); 9 10 END; 11 / 6 7 124 4 Процедура PL/SQL успешно завершена.
Как в школьном курсе математики 2 * 2 всегда равно 4! (А не три и не пять это надо знать!) :) Теперь давайте рассмотрим, как же можно удалить пакет. Достаточно просто. Применить оператор DDL - DROP. Вот так:
DROP PACKAGE test_pkg /
Получаем:
SQL> DROP PACKAGE test_pkg 2 / Пакет удален.
При этом удаляется весь пакет! Больше ничего определять не нужно. Давайте убедимся в этом:
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS FROM USER_OBJECTS WHERE OBJECT_TYPE IN ('PACKAGE', 'PACKAGE BODY') /
Получаем:
SQL> SELECT OBJECT_NAME, OBJECT_TYPE, STATUS 2 FROM USER_OBJECTS 3 WHERE OBJECT_TYPE = 'PACKAGE BODY' 4 / OBJECT_NAME OBJECT_TYPE STATUS -------------------------- ------------------ ------- 0 строк выбрано!
То есть делали мы делали и все бесполезно! Но, думаю только не для вас! А, это самое главное. Проделайте все еще раз и закрепите полученные навыки. :)