Упрощенный синтаксис этого оператора имеет следующий вид:
□ 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 (такой триггер известен