Шаг 98 - PL/SQL - Пакеты - Изменение, удаление

Теперь возьмем ситуацию, когда нам нужно добавить в пакет функцию умножающую два числа. Определенную вот так:

-- 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 строк выбрано! 

То есть делали мы делали и все бесполезно! Но, думаю только не для вас! А, это самое главное. Проделайте все еще раз и закрепите полученные навыки. :)


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Летучий Сергей.