Miks peaks eelistama trigerite puhul tingimuse kirjutamist päises olevasse WHEN klauslisse, selle asemel, et kirjutada see kehandis olevasse IF lausesse?

Postitas Erki Eessaar
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;

Hinda postitust:

Keskmine hinne : Pole veel hinnanguid!