Выбрать главу

Упрощенный синтаксис этого оператора имеет следующий вид:

□ CREATE [OR REPLACE] PACKAGE BODY имя_пакета

{ IS | AS}

те л о _ п а к е та

END имя_пакета;

где

■ имя_пакета определяет имя пакета, которое должно совпадать с именем,

ранее определенным в спецификации пакета,

■ те л о _ п а к е та содержит код процедур и функций.

В следующем примере создается тело пакета для product_package:

□ CREATE PACKAGE BODY p ro d u c t_ p a c k a g e AS

FUNCTION g e t _ p r o d u c t s _ r e f _ c u r s o r

RETURN t _ r e f _ c u r s o r IS

v_p r o d u c t s _ r e f _ c u r s o r t _ r e f _ c u r s o r ;

BEGIN

- - получить значение REF CURSOR

OPEN v _ p r o d u c t s _ r e f _ c u r s o r FOR

SELECT p r o d u c t _ id , name, p r i c e

FROM p r o d u c t s ;

— в о з в р а ти т ь REF CURSOR

RETURN v _ p r o d u c t s _ r e f _ c u r s o r ;

END g e t _ p r o d u c t s _ r e f _ c u r s o r ;

PROCEDURE u p d a t e _ p r o d u c t _ p r i c e (

p _ p r o d u c t _ id IN p r o d u c t s .p ro d u c t_ id% T Y P E ,

p _ f a c t o r IN NUMBER

) AS

v _ p r o d u c t _ c o u n t INTEGER;

BEGIN

— подсчитывает количе с тво тов ар ов с

- - предложенным v _ p r o d u c t _ id (должно быть равно 1, если то в ар с уще с т в у е

т )

SELECT COUNT(*)

Знакомство с программированием на PL/SQL 383

INTO v _ p r o d u c t_ c o u n t

FROM p r o d u c t s

WHERE p r o d u c t _ id = p _ p r o d u c t_ id ;

— если тов ар с уще с т в у е т ( v _ p r o d u c t_ c o u n t =1 ) ,

— обновить цену э т о г о товара

I F v _ p r o d u c t _ c o u n t = 1 THEN

UPDATE p r o d u c t s

SET p r i c e = p r i c e * p _ f a c t o r

WHERE p r o d u c t _ id = p _ p r o d u c t_ id ;

COMMIT;

END IF;

EXCEPTION

WHEN OTHERS THEN

— выполнить о т к а т , если возникло исключение

ROLLBACK;

END u p d a t e _ p r o d u c t _ p r i c e ;

END p ro d u c t_ p a c k a g e ;

/

Функция g e t _ p r o d u c t s _ r e f _ c u r s o r ( ) открывает курсор и выбирает в

него столбцы p r o d u c t _ id , name и p r i c e из таблицы p r o d u c t s . Функция возвращает

ссылку на этот курсор (REF CURSOR), хранимую в v _ p r o d u c t s _ r e f _

c u r s o r . Затем к этому REF CURSOR можно обращаться для чтения значений

столбцов.

Процедура u p d a t e _ p r o d u c t _ v _ p r i c e ( ) обновляет цену товара и сохраняет

изменение. Эта процедура идентична процедуре, показанной ранее в разделе

“Создание процедуры” , поэтому мы не будем вновь вдаваться в подробности

того, как она работает.

Вызов процедур и функций в пакете

При вызове входящих в пакет процедур и функций вы должны включать

в вызов имя пакета. Следующий пакет вызывает процедуру product_

package.get_products_ref_cursor(), которая возвращает ссылку на курсор,

содержащий значения product_id, name и price для товаров:

□ SELECT product_package.get_products_ref_cursor

FROM dual;

GET_PRODUCTS_REF_CUR

CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

PRODUCT_ID NAME PRICE

1 Modern S c ie n c e

2 C h em i s t r y

3 Supe rno va

1 9 .9 5

30

2 5 .9 9

384 Глава 11

4 Tank War 13 .9 5

5 Z F i l e s 4 9 .9 9

5 2412: The Re tu rn 14 .9 5

7 Space F o r c e 9 13 .4 9

8 From A n o th e r P la n e t 12 .9 9

9 C l a s s i c a l Mu s ic 1 0 .9 9

10 Pop 3 15 .9 9

11 C r e a t i v e Y e l l 14 .9 9

12 My F r o n t L in e 13.

В следующем примере процедура p r o d u c t .p a c k a g e . u p d a t e _ p ro d u c t_

p r i c e ( ) вызывается для умножения цены товара № 3 на 1.25:

□ CALL p r o d u c t _ p a c k a g e .u p d a t e _ p r o d u c t _ p r i c e ( 3 , 1 .2 5 ) ;

Следующий запрос получает информацию о товаре № 3; обратите внимание,

что цена товара увеличена:

□ SELECT price

FROM products

WHERE product_id = 3;

PRICE - '

3 2 .4 9

Получение информации о процедурах и функциях из пакета

Информацию о процедурах и функциях вашего пакета можно получить из

представления u s e r _ p r o c e d u r e s (см. выше). В следующем примере из user_

procedures извлекаются значения столбцов o b je c t_ n ame и procedure_name

для пакета p ro d u c t_ p a c k a g e :

□ SELECT object_name, procedure_naine

FROM user_procedures

WHERE object_name = 'PRODUCT.PACKAGE’;

OBJECT_NAME PROCEDURE.NAME

PRODUCT.PACKAGE GET_PRODUCTS_REF_CURSOR

PRODUCT.PACKAGE UPDATE_PRODUCT_PRICE

Удаление пакета

Для удаления пакета используется оператор DROP PACKAGE. Следующий оператор

удаляет product_package:

□ DROP PACKAGE p r o d u c t .p a c k a g e ;

Триггеры

Триггером называется процедура, которая автоматически выполняется

базой данных (или, говоря техническими терминами, срабатывает), когда

для определенной таблицы базы данных выполняется определенный oneЗнакомство

с программированием на PL/SQL 385

ратор языка манипулирования данными (DM L ) SQL - INSERT, UPDATE или

DELETE. Триггеры бывают полезны для выполнения расширенного аудита

изменений, вносимых в значения столбцов таблицы.

Когда выполняются триггеры

Триггер может быть выполнен перед оператором SQL или после него.

Кроме того, поскольку оператор DML может одновременно повлиять более

чем на одну строку, код процедуры для триггера может быть выполнен

для каждой строки, на которую влияет оператор SQL (такой триггер известен