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

Задача. Триггер зеркалирования.

Создать таблицу KK_CLIENT(CLIENT_ID INTEGER, CLIENT_NAME VARCHAR2(40), AMOUNT NUMBER). У таблицы KK_CLIENT имеется первичный ключ CLIENT_ID.

Создать таблицу KK_CLIENT_MINUS - копию таблицы KK_CLIENT.

Написать триггер на KK_CLIENT, который в случае insert-ов, update-ов и delete-ов в KK_CLIENT зеркалирует изменения в таблицу KK_CLIENT_MINUS, т.е. всё время поддерживает, что в KK_CLIENT_MINUS всегда лежит копия KK_CLIENT, но только для отрицательных значений поля AMOUNT.

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

CREATE TABLE KK_CLIENT(CLIENT_ID INTEGER, CLIENT_NAME VARCHAR2(40), AMOUNT NUMBER);

CREATE TABLE KK_CLIENT_MINUS(CLIENT_ID INTEGER, CLIENT_NAME VARCHAR2(40), AMOUNT NUMBER);

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

CREATE OR REPLACE TRIGGER KK_TRIG_AIUD_KK_CLIENT

AFTER INSERT OR UPDATE OR DELETE ON KK_CLIENT

FOR EACH ROW

BEGIN

IF (DELETING OR UPDATING) AND :OLD.AMOUNT < 0 THEN

DELETE FROM KK_CLIENT_MINUS WHERE CLIENT_ID = :OLD.CLIENT_ID;

END IF;

IF (INSERTING OR UPDATING) AND :NEW.AMOUNT < 0 THEN

INSERT INTO KK_CLIENT_MINUS

(CLIENT_ID, CLIENT_NAME, AMOUNT)

VALUES

(:NEW.CLIENT_ID, :NEW.CLIENT_NAME, :NEW.AMOUNT);

END IF;

END KK_TRIG_AIUD_KK_CLIENT;

Проверим:

insert into kk_client(client_id, client_name, amount) values (1, 'a', 10);

select client_id, client_name, amount from kk_client;

select client_id, client_name, amount from kk_client_minus;

insert into kk_client(client_id, client_name, amount) values (2, 'b', -10);

select client_id, client_name, amount from kk_client;

select client_id, client_name, amount from kk_client_minus;

update kk_client set amount = 20 where client_id = 1;

select client_id, client_name, amount from kk_client;

select client_id, client_name, amount from kk_client_minus;

update kk_client set amount = -20 where client_id = 2;

select client_id, client_name, amount from kk_client;

select client_id, client_name, amount from kk_client_minus;

update kk_client set amount = 20 where client_id = 2;

select client_id, client_name, amount from kk_client;

select client_id, client_name, amount from kk_client_minus;

update kk_client set amount = -30;

select client_id, client_name, amount from kk_client;

select client_id, client_name, amount from kk_client_minus;

update kk_client set amount = 20 where client_id = 2;

select client_id, client_name, amount from kk_client;

select client_id, client_name, amount from kk_client_minus;

delete from kk_client where client_id = 2;

select client_id, client_name, amount from kk_client;

select client_id, client_name, amount from kk_client_minus;

delete from kk_client where client_id = 1;

select client_id, client_name, amount from kk_client;

select client_id, client_name, amount from kk_client_minus;

Задача. Триггер по поиску в справочнике.

Дана таблица REGION(ID, NAME) с кодами и названиями регионов. Создать таблицу CLIENTS(ID, NAME, REGION_ID, REGION_NAME). Пользователь через форму ввода вставляет в таблицу CLIENTS имя клиента и строку с регионом. Требуется написать триггер на таблицу CLIENTS. Триггер автоматом вставляет ID (из сиквенса) и REGION_ID (из справочника REGION). Если записи нет в справочнике, то триггер вставляет запись в справочник.

Создадим таблицы и соответствующие им сиквенсы по генерации первичных ключей, заполним справочник данными:

CREATE TABLE REGION (ID INTEGER, NAME VARCHAR2(30));

CREATE TABLE CLIENTS (ID INTEGER, NAME VARCHAR2(30), REGION_ID INTEGER, REGION_NAME VARCHAR2(30));

CREATE SEQUENCE SQ_REGION;

CREATE SEQUENCE SQ_CLIENTS;

insert into region(id,name) values (sq_region.nextval,'Москва');

insert into region(id,name) values (sq_region.nextval,'Петербург');

create or replace trigger trig_biu_clients

before insert or update on clients

for each row

declare

v_region_id integer;

begin

/* сгенерируем новый clients.id */

if inserting then

select sq_clients.nextval into :new.id from dual;

end if;

/* найдем, есть ли в справочнике region запись с вставляемым названием региона. используем max(), чтобы избежать exception, если данные не найдены */

select max(region.id)

into v_region_id

from region

where region.name = :new.region_name;

/* если записи нет, то сгенерим новый первичный ключ для справочника region и вставим в справочник запись с этим ключом */

if v_region_id is null then

select sq_region.nextval into v_region_id from dual;

insert into region (id, name) values (v_region_id, :new.region_name);

end if;

/* в поле clients.region_id триггер записывает найденный или вновь сгенерированный v_region_id из справочника*/

:new.region_id := v_region_id;

end trig_biu_clients;

Проверяем, как работает триггер:

insert into clients (name, region_name) values ('Вася', 'Москва');

select * from clients;

insert into clients (name, region_name) values ('Петя', 'Рязань');

select * from clients;

select * from region;

update clients set region_name = 'Петербург' where name = 'Вася';

select * from clients;

update clients set region_name = 'Новгород' where name = 'Петя';

select * from clients;

select * from region;

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