Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
РСБДтЗ / Курс лекций РСБДиЗ.doc
Скачиваний:
135
Добавлен:
05.03.2016
Размер:
1.63 Mб
Скачать

Триггеры Oracle Подготовка примера

drop table test;

create table test(i integer primary key, s varchar2(100));

begin

delete from test;

insert into test values(1, 'aaa');

insert into test values(2, 'bbb');

commit;

end;

create sequence test_s start with 1;

Создание триггера

drop trigger t;

create or replace trigger t_i

before insert /* or update or delete */

-- after insert /* or update or delete */

on test

for each row

when (new.i is null)

begin

dbms_output.put_line('trigger ok');

select test_s.nextval into :new.i from dual;

end;

create or replace trigger t_i

before insert /* or update or delete */

-- after insert /* or update or delete */

on test

referencing new as NN old as OO

for each row

when (nn.i is null)

begin

dbms_output.put_line('trigger ok');

select test_s.nextval into :nn.i from dual;

end;

Типы триггеров и порядок их выполнения

Пример показывает порядок выполнения триггеров всех типов

drop table t;

create table t(i integer);

create or replace trigger tb_d

before delete on t

begin

dbms_output.put_line('tb_d');

end;

create or replace trigger tbr_d

before delete on t

for each row

begin

dbms_output.put_line('tbr_d');

end;

create or replace trigger ta_d

after delete on t

begin

dbms_output.put_line('ta_d');

end;

create or replace trigger tar_d

after delete on t

for each row

begin

dbms_output.put_line('tar_d');

end;

begin

insert into t values(1);

insert into t values(2);

end;

Использование предикатов inserting, ... И new, old

drop table test_log;

create table test_log(op_user varchar2(100),

op_date date, i integer, s varchar2(100));

create or replace trigger t_ud

before update of i, s or delete

on test

for each row

begin

if updating('s') then

if :new.s > :old.s then

raise_application_error(-20000, 'update error');

end if;

elsif deleting then

insert into test_log values(user, sysdate, :old.i, :old.s);

end if;

end;

Выполнение триггреров в той же транзакции

delete from test;

select * from test_log;

rollback;

select * from test_log;

Активизация и деактивизация триггеров

alter trigger t_ud disable;

alter table test enable all triggers;

Получение информации о триггерах

select * from user_triggers;

select * from user_objects;

Запрет изменения new, old в after ... и table level триггерах

create or replace trigger ta_ud

after update

on test

for each row

begin

:new.s := 'aaaaaaa';

end;

create or replace trigger ta_ud

before update

on test

for each row

begin

:old.s := 'aaaaaaa';

end;

create or replace trigger tb_ud

before update

on test

begin

:new.s := 'aaaaaaa';

end;

Несколько триггеров одного типа

create or replace trigger ta_ud1

after update

on test

for each row

begin

dbms_output.put_line('trigger update 1');

end;

create or replace trigger ta_ud2

after update

on test

for each row

begin

dbms_output.put_line('trigger update 2');

end;

Использование исключений

create or replace package p_exc

as

invalid_str exception;

end;

create or replace trigger t_ui

before insert or update

on test

for each row

begin

if :new.s < 'c' then

raise p_exc.invalid_str;

end if;

end;

begin

delete from test;

commit;

insert into test values(1, 'aaa');

exception

when p_exc.invalid_str then

dbms_output.put_line

('invalid_str: ' || sqlcode || ' ' || sqlerrm);

end;

Триггеры instead of

create table tp(i integer primary key);

create table tc(k integer primary key, i integer references tp(i));

begin

commit;

delete from tc;

delete from tp;

commit;

insert into tp values(1);

insert into tp values(2);

insert into tc values(5, 1);

insert into tc values(6, 1);

insert into tc values(7, 2);

commit;

end;

create or replace view v as select tp.i ii, tc.k kk from

tp inner join tc on tp.i = tc.i;

select * from user_updatable_columns where table_name = 'V';

create or replace trigger vt

instead of insert

on v

for each row

declare

ii integer;

begin

begin

select i into ii from tp where i = :new.ii;

exception

when no_data_found then

insert into tp(i) values(:new.ii);

end;

update tc set i = :new.ii where k = :new.kk;

if sql%rowcount = 0 then

insert into tc(k, i) values(:new.kk, :new.ii);

end if;

end;

Соседние файлы в папке РСБДтЗ