Vastus: Stackoverflow arutelus pakub kasutaja
Elad ühe ülesande lahendusena välja variandid A ja B. Variandi A korral on tingimus trigeri kehandis IF klauslis. Variandi B korral on tingimus trigeri päises WHEN klauslis. Trigereid on seetõttu kaks, mitte üks.
Tõsi on, et muudatuste tegemiseks on variandi A korral mõnikord vaja käivitada vähem lauseid kui variandi B korral. Kui ma tahan muuta trigeri loogikat, siis tuleb käivitada kaks lauset: DROP TRIGGER ja CREATE TRIGGER. Kui terve loogika on trigeri funktsioonis siis CREATE OR REPLACE FUNCTION lause on muudatuseks piisav.
Kuid sama saab ka öelda B kohta - kui tahan näiteks lõpetada reageerimise UPDATE sündmusele, siis DROP TRIGGER ja CREATE OR REPLACE FUNCTION lausete asemel piisab DROP lausest.
Variant B eeliseks on, et IF lausete sees olevat koodi ei dubleerita ja seetõttu on ka funktsioon lihtsam.
Minu arvates on R.C. Martini puhta koodi raamatu halbade lõhnade kataloogi (peatükk 17) kohaselt lahendusel A järgmised halvad lõhnad:
- G5: Duplication
- G30: Functions Should Do One Thing
(Kuidas kasutada O'Reilly digitaalset platvormi?)
Lisaks võtab variant A andmebaasisüsteemilt võimaluse teostada optimeerimist, mille kohaselt käivitatakse ja läbitakse trigeri funktsioon ainult siis, kui selleks on tõesti vajadus (st tingimused on täidetud).
Lõpetuseks on variant B ka veidi paremini kooskõlas üldise relatsiooniliste/SQL-andmebaaside ideoloogiaga, mille kohaselt tegevused toimuvad indiviidide hulkadega, mitte üksikute indiviididega.
Variandile A vastab algoritm:
FOR EACH huvipakkuv objekt o
IF o.rahuldab_tingimust
o.tee_tegevus
END IF;
END;
ja variandile B vastab algoritm:
FOR EACH huvipakkuv objekt o WHERE o.rahuldab_tingimust
o.tee_tegevus
END;