--TRIGGERY
--
--Trigger je kod, ktery je automaticky spusten pri nejake udalosti. Touto
--udalosti mohou byt systemove akce typu prihlaseni apod. Pro bezne uzivatele
--jsou nejdulezitejsi udalosti vazici se k modifikaci dat v tabulce.
--
--Syntax:
--
--CREATE [OR REPLACE] TRIGGER jmeno {BEFORE|AFTER|INSTEAD OF}
--udalost [REFERENCING OLD AS o NEW AS n] [FOR EACH ROW] [WHEN (podminka)]
--blok
--
--Udalost muze vypadat jako OR nasledujicich moznosti:
--DELETE
--INSERT
--UPDATE [OF sloupec, ...]
--ON tabulka
--
--INSTEAD OF triggery nas ted nezajimaji (slouzi pro pohledy),
--BEFORE triggery jsou spousteny pred provedenim udalosti,
--AFTER triggery jiz po provedeni udalosti.
--
--Trigger je spusten budto jednou pri provadeni prikazu (default) nebo pro
--kazdy meneny radek (FOR EACH ROW).
--
--[Pro triggery typu FOR EACH ROW]
--Pri zmene mam k dispozici promenne :new s novou hodnotou a :old s puvodni
--hodnotou. BEFORE trigger muze menit hodnoty :new a tim ovlivnovat data.
--(pokud se mi nelibi nazvy new a old (napr. koliduji s nazvy sloupcu),
--mohu si je prejmenovat v klauzuli REFERENCING).
--
--Trigger je spusten jen, je-li splnena podminka v casti WHEN.
--
--Podminky: INSERTING, UPDATING, DELETING
--
--IF INSERTING THEN . . . END IF;
--IF UPDATING THEN . . . END IF;
--IF DELETING THEN . . . END IF;
SQL> DROP TABLE platy;
SQL> CREATE TABLE platy(uco NUMBER, uvazek NUMBER, sazba NUMBER, plat NUMBER);
-- Trigger pro aktualizaci platu podle sazby a uvazku:
CREATE OR REPLACE TRIGGER Aktualizuj_plat
BEFORE INSERT OR UPDATE ON platy
FOR EACH ROW
DECLARE
BEGIN
:new.plat:=:new.sazba*:new.uvazek;
END;
/
Trigger created.
SQL> INSERT INTO platy VALUES (1,100,5,0);
1 row created.
SQL> SELECT * FROM platy;
UCO UVAZEK SAZBA PLAT
---------- ---------- ---------- ----------
1 100 5 500
-- Trigger pro hlidani, aby uvazek nebyl vyssi nez 200
CREATE OR REPLACE TRIGGER Hlidej_plat
BEFORE INSERT OR UPDATE OF uvazek ON platy
FOR EACH ROW
DECLARE
BEGIN
IF :new.uvazek>200 THEN :new.uvazek:=200;
END IF;
END;
/
Trigger created.
-- trigger opravi hodnotu uvazku na 200 pri vkladani
SQL> INSERT INTO platy VALUES (3,500,400,0);
1 row created.
SQL> SELECT * FROM platy;
UCO UVAZEK SAZBA PLAT
---------- ---------- ---------- ----------
1 100 5 500
3 200 400 80000
-- trigger opravi hodnotu uvazku na 200 pri ukatualizace jiz vlozene polozky
SQL> UPDATE platy SET uvazek=400 WHERE uco=1;
1 row updated.
SQL> SELECT * FROM platy;
UCO UVAZEK SAZBA PLAT
---------- ---------- ---------- ----------
1 200 5 1000
3 200 400 80000
-- Priklad: logovani zmeny platu
SQL> DROP TABLE platy_log;
SQL> CREATE TABLE platy_log(kdy DATE, uco NUMBER, puvodni NUMBER, novy NUMBER);
CREATE OR REPLACE TRIGGER loguj_zmeny_platu
AFTER INSERT OR DELETE OR UPDATE ON platy
FOR EACH ROW
DECLARE
BEGIN
INSERT INTO platy_log VALUES(sysdate,:new.uco,:old.plat,:new.plat);
END;
/
Trigger created.
-- spusteni trigerru
SQL> INSERT INTO platy VALUES (4,100,10,0);
1 row created.
SQL> SELECT * FROM platy_log;
KDY UCO PUVODNI NOVY
--------- ---------- ---------- ----------
12-APR-05 4 1000
SQL> DROP TABLE platy_log2;
SQL> CREATE TABLE platy_log2(kdy DATE, uco NUMBER, typ_zmeny VARCHAR2(20));
-- Trigger pro logovani typu upravy
CREATE OR REPLACE TRIGGER loguj_zmeny
AFTER INSERT OR DELETE OR UPDATE ON platy
FOR EACH ROW
DECLARE
BEGIN
if INSERTING then
INSERT INTO platy_log2 VALUES(sysdate,:new.uco,'Insert');
end if;
if UPDATING then
INSERT INTO platy_log2 VALUES(sysdate,:old.uco,'Update');
end if;
if DELETING then
INSERT INTO platy_log2 VALUES(sysdate,:old.uco,'Delete');
end if;
END;
/
Trigger created.
-- spusteni trigerru
SQL> INSERT INTO platy VALUES (5,100,10,0);
1 row created.
SQL> UPDATE platy SET uvazek = 150 WHERE uco = 3;
1 row updated.
SQL> DELETE FROM platy;
4 rows deleted.
SQL> SELECT * FROM platy_log2;
KDY UCO TYP_ZMENY
--------- ---------- --------------------
12-APR-05 5 Insert
12-APR-05 3 Update
12-APR-05 1 Delete
12-APR-05 3 Delete
12-APR-05 4 Delete
12-APR-05 5 Delete
6 rows selected.