PHPPamokos.lt


10. Stebime pakeitimus su TRIGGERS

Dar viena kiek rečiau naudojama SQL struktūra yra trigeriai. Jie kviečiami, kai reikia automatiškai stebėti duomenų pasikeitimus - sakykime, įvykus vienam veiksmui, automatiškai iškviesti kitą susijusį veiksmą.

Yra trijų tipų trigeriai - skirstomi pagal tai, kuriam veiksmui jie kviečiami: INSERT, UPDATE ar DELETE. Sakykime, ištrynus konkrečią eilutę, reikia sukurti kažkokį įrašą apie ją atskiroje lentelėje, kad visiškai neprarastume duomenų.

Taip pat galime pasirinkti, kuriuo metu vykdyti trigerį - ar prieš pagrindinį veiksmą (BEFORE), ar po jo (AFTER).

Štai visaverčio trigerio sukūrimo pavyzdys - prieš trynimą iš lentelės orders įrašome ištrintą įrašą į istorijos lentelę:

DELIMITER //

CREATE TRIGGER trigger_insert
BEFORE DELETE
   ON orders FOR EACH ROW
BEGIN
	INSERT INTO cancelled_orders VALUES (OLD.product_id, NOW());
END; //

DELIMITER ;

Kaip matote, yra komanda CREATE TRIGGER, po kurios seka jūsų sugalvotas trigerio pavadinimas, tada nurodome kuriuo metu vykdyti trigerį (BEFORE DELETE), tada nurodome lentelę orders ir tarp BEGIN .. END jau nurodome konkrečius veiksmus, kaip procedūroje.

Lygiai taip pat, kaip ir kuriant procedūrą, reikia laikinai pakeisti DELIMITER simbolį į bet kokį kitą, ir po to jį grąžinti į kabliataškį.

Kitas pavyzdys - atnaujinant eilutę, įrašyti keitimo faktą irgi į veiksmų žurnalą:

DELIMITER //

CREATE TRIGGER trigger_insert
AFTER UPDATE
   ON orders FOR EACH ROW
BEGIN
	INSERT INTO updated_orders VALUES (NEW.product_id, OLD.product_id, NOW());
END; //

DELIMITER ;

Kaip matote, trigeriuose figūruoja du skirtingi kaip kintamieji - NEW ir OLD. Jie turbūt savaime suprantami - reikšmė prieš pakeitimą ir po jo. Tiesa, INSERT-tipo trigeriuose OLD neegzistuoja, nes reikšmė yra tik nauja. Ir analogiškai DELETE-tipo trigeriuose neegizstuoja NEW, nes eilutės tiesiog nebėra.

Sukūrus trigerį, daugiau nieko daryti ir jį kviesti nereikia - jis atliks savo darbą automatiškai. Pabandome patikrinti - sakykime, turime tokius duomenis lentelėse:

Ir atliekame DELETE veiksmą:

DELETE FROM orders WHERE id = 2;

Žiūrime, kas gavosi lentelėje cancelled_orders - turėkite omenyje, kad rankomis nieko į ją neįterpinėjome, įrašas buvo įrašytas automatiškai:

Trigeriai, išoriniai raktai ir kada ką naudoti

Atrodo, kad trigeriai yra labai patogus dalykas, kurį reikėtų naudoti visuomet, norint sekti duomenų pasikeitimus ar gal net juos uždrausti. Bet reikia nepainioti su panašiais veiksmais, kuriuos už mus jau atlieka lentelių išoriniai raktai. Ar pamenate kas yra FOREIGN KEY? O gal pamenate, kad jų kūrimo struktūroje yra sąlygos ON UPDATE ir ON DELETE? Tai čia irgi yra savotiški trigeriai - atlikus veiksmą, atliekamas kitas veiksmas. Bet išorinių raktų pliusas - jie paprastesni skaitymui ir suvokimui struktūroje. Trigeriai gi yra naudojami rečiau.

Tai taip pat susiję ir su duomenų bazės bei viso projekto architektūra. Trigeriai nėra taip gerai matomi per phpMyAdmin ar per kitus įrankius - kaip taisyklė, naujas programuotojas net nepamatys kad projekte yra trigerių, kol kas nors jo apie tai neperspės, arba kol pats nepradės kapstytis, kodėl įvyksta kažkokie keisti veiksmai, kurių pats jis nekvietė.

Tai lygiai kaip STORED PROCEDURES atveju, trigerius reikia vartoti saikingai - populiariausias pavyzdys ir yra įrašų įrašymas į istorijos ar loginimo lentelę. Kitiems atvejams dažniausiai įmanoma išsiversti be trigerių.

Apibendrinimas

Trigetiai yra puikus įrankis duomenų bazės duomenų pasikeitimų stebėjimui, bet juos reikia naudoti saikingai - tik tada, kai žinote jog tai apsimoka. bet kuriuo atveju, kad apie tokius dalykus žinosite - tikrai nepamaišys.



(c) 2015-2018. Visais klausimais kreipkitės povilas@laraveldaily.com