Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Oracle Tutorial.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
401.64 Кб
Скачать

Триггеры.

Триггеры чаще всего "вешаются" на таблицы. В триггерах пишут, какие действия нужно совершить перед изменением данных в таблице или после изменения данных в таблице. По этому признаку триггеры бывают BEFORE и AFTER. Триггеры можно "вешать" на события INSERT, UPDATE, DELETE. В триггерах можно проверять, какое именно из действий совершается (IF inserting THEN ..., IF updating THEN ..., IF deleting THEN ..., ), а также обращаться к предыдущим и новым значениям полей (например, v_old_id := :old.ID; :new.ID := v_new_id).

Подробности мы разберем в задачах ниже.

Задача. Автоинкрементное поле.

Создать таблицу KK_14 с полями ID и VAL, создать сиквенс SQ_KK_14.

Написать BEFORE INSERT триггер, который делает следующее: если при вставке в KK_14 не указано ID, то значение ID берется из сиквенса SQ_KK_14. Это реализация автоинкрементного поля.

Создадим таблицу и сиквенс:

CREATE TABLE KK_14(ID NUMBER, VAL VARCHAR2(20));

CREATE SEQUENCE SQ_KK_14;

Создадим триггер:

CREATE OR REPLACE TRIGGER KK_TRIG_BI_KK_14

BEFORE INSERT ON KK_14

FOR EACH ROW

BEGIN

IF :NEW.ID IS NULL THEN

SELECT SQ_KK_14.NEXTVAL INTO :NEW.ID FROM DUAL;

END IF;

END KK_TRIG_BI_KK_14;

Вставляем строки, не указав значения поля ID:

INSERT INTO KK_14(VAL) VALUES ('FJI');

INSERT INTO KK_14(VAL) VALUES ('SDA');

Проверяем, что ID заполнились из сиквенса:

SELECT * FROM KK_14;

Задача. Триггер конвертации сумм в валюте.

Дана таблица курсов KK_RATE (RATE_DATE - дата курса, CURRENCY_CODE - код валюты, RATE - сам курс).

Дана таблица платежей KK_PAYMENT (PAYMENT_DATE - дата платежа, CURRENCY_CODE - код валюты, PAYMENT_SUM_IN_CURRENCY – сумма платежа в валюте CURRENCY_CODE, PAYMENT_SUM_IN_RUB - сумма платежа, пересчитанная в рублях).

Требуется создать BEFORE INSERT OR UPDATE триггер, который по заданным полям PAYMENT_DATE, CURRENCY_CODE, PAYMENT_SUM_IN_CURRENCY автоматически рассчитывает поле PAYMENT_SUM_IN_RUB согласно таблице курсов KK_RATE.

Если курс не найден, выдавать об этом сообщение в dbms_output, но оставлять в PAYMENT_SUM_IN_RUB null.

Создадим таблицы:

create table KK_RATE

(

rate_date DATE,

currency_code INTEGER,

rate NUMBER(6,2)

);

insert into KK_RATE(RATE_DATE, CURRENCY_CODE, RATE) values(to_date('22.03.2012','dd.mm.yyyy'), 840, 29.43);

insert into KK_RATE(RATE_DATE, CURRENCY_CODE, RATE) values(to_date('23.03.2012','dd.mm.yyyy'), 840, 29.35);

insert into KK_RATE(RATE_DATE, CURRENCY_CODE, RATE) values(to_date('22.03.2012','dd.mm.yyyy'), 978, 38.42);

insert into KK_RATE(RATE_DATE, CURRENCY_CODE, RATE) values(to_date('23.03.2012','dd.mm.yyyy'), 978, 38.45);

create table KK_PAYMENT

(

payment_date DATE,

currency_code INTEGER,

payment_sum_in_currency NUMBER(6,2),

payment_sum_in_rub NUMBER(6,2)

);

Создадим решающий задачу триггер:

CREATE OR REPLACE TRIGGER KK_TRIG_BIU_KK_PAYMENT

BEFORE INSERT OR UPDATE ON KK_PAYMENT

FOR EACH ROW

DECLARE

V_RATE KK_RATE.RATE%TYPE;

BEGIN

BEGIN

SELECT RATE

INTO V_RATE

FROM KK_RATE

WHERE KK_RATE.CURRENCY_CODE = :NEW.CURRENCY_CODE

AND KK_RATE.RATE_DATE = :NEW.PAYMENT_DATE;

EXCEPTION

WHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE('RATE NOT FOUND');

END;

:NEW.PAYMENT_SUM_IN_RUB := V_RATE * :NEW.PAYMENT_SUM_IN_CURRENCY;

END KK_TRIG_BIU_KK_PAYMENT;

Осуществим проверочные вставки, указываем 3 поля, 4ое рассчитывается триггером:

INSERT INTO KK_PAYMENT(PAYMENT_DATE, CURRENCY_CODE, PAYMENT_SUM_IN_CURRENCY) VALUES(TO_DATE('22.03.2012', 'DD.MM.YYYY'), 840, 100);

INSERT INTO KK_PAYMENT(PAYMENT_DATE, CURRENCY_CODE, PAYMENT_SUM_IN_CURRENCY) VALUES(TO_DATE('23.03.2012', 'DD.MM.YYYY'), 978, 100);

INSERT INTO KK_PAYMENT(PAYMENT_DATE, CURRENCY_CODE, PAYMENT_SUM_IN_CURRENCY) VALUES(TO_DATE('30.10.1980', 'DD.MM.YYYY'), 840, 2);

Смотрим результат (в т. ч. DBMS_OUTPUT после каждой вставки):

SELECT * FROM KK_PAYMENT;

Сделаем update:

UPDATE KK_PAYMENT

SET PAYMENT_SUM_IN_CURRENCY = 200

WHERE PAYMENT_DATE = TO_DATE('23.03.2012', 'DD.MM.YYYY')

AND CURRENCY_CODE = 978

AND PAYMENT_SUM_IN_CURRENCY = 100;

Смотрим результат:

SELECT * FROM KK_PAYMENT;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]