140 likes | 528 Views
TRIGERI. Trigeri u MySQL -u. Šta su trigeri ? Trigeri su objekti ( uskladi štene procedure) pridruženi tabeli, koji se automatski aktiviraju kada se desi neki događaj vezan za tu tabelu. Uvedeni su u verziji 5.02 Alpha
E N D
Trigeri u MySQL-u • Šta su trigeri ? Trigeri su objekti (uskladištene procedure) pridruženi tabeli, koji se automatski aktiviraju kada se desi neki događaj vezan za tu tabelu. • Uvedeni su u verziji 5.02 Alpha Mogu se uspešno koristiti za validaciju podataka i druge operacije direktno nad tabelama baze podataka. • Kada se trigeri aktiviraju ? Trigeri se aktiviraju kada se desi neka promena u pridruženoj tabeli, preciznije prilikom izvršenja Insert / Update / Delete naredbi.
Trigeri u MySQL-u • Trigeri ne mogu biti korišćeni u SELECT naredbi na isti način kao procedura ili funkcija. • Kreiranje trigera – sintaksa CREATE TRIGGER naziv_trigera vreme_izvršavanja_trigera događaj ON tbl_name FOR EACH ROW trigger_stmt
Trigeri u MySQL-u Vreme izvršavanja trigera: • BEFORE • AFTER Događaj je ona akcija čije izvršavanje na pridruženoj tabeli uzrokuje aktiviranje trigera. Može biti: • INSERT • UPDATE • DELETE
Trigeri u MySQL-u Primer :Validacija vrednosti polja CREATE TABLE test (id INT, sum DECIMAL(10,2)); DELIMITER $$ CREATE TRIGGER insert_trig BEFORE INSERT ON test FOR EACH ROW BEGIN IF new.sum<0 THEN SET new.sum=0; ENDIF; END$$ DELIMITER;
Trigeri u MySQL-u Kako trigeri funkcionišu ? • Ključna reč BEFORE opredeljuje vreme izvršenja trigera. U ovom slučaju, triger će biti aktiviran pre svakog novog upisa zapisa u tabelu test. • Ključne reči FOR EACH ROW označavaju da će triger biti izvršen za svaki novi slog. • Ključne reči OLD i NEW nam omogučavaju pristup vrednostima polja u zapisima na koje se odnosi triger. • U INSERT trigeru može se koristiti samo NEW.ime_polja • U DELETE trigeru može se koristiti samo OLD.ime_polja
Trigeri u MySQL-u • OLD i NEW • Ključne rečiOLDiNEWse koriste za pristup podacima u zapisima tabele. OLD se koristi za vrednosti polja pre promene, a NEW sadrži vrednost polja posle promene. • U programu, polju koje se zove emp_name možemo pristupiti na sledeći način:new.emp_name • Primer: create trigger bi_zaposleni_fer before insert on zaposleni for each row set new.ime := reverse(new.ime);
Trigeri u MySQL-u • Da bi se triger aktivirao potrebno je da zapis bude dodat u odgovarajuću tabelu. Primer: insert into zaposleni (zaposleni,ime) values (4,’Pera’);
Trigeri u MySQL-u • Kompleksni trigeri • Trigeri koji sadrže više od jedne linije koda • Tada se koriste ključne reči BEGIN i END koje imaju svrhu da označe kompajleru početak i kraj koda trigera • Brisanje trigera DROP TRIGGER naziv_trigera; • Prikazivanje trigera SHOW TRIGGERS;
Trigeri u MySQL-u Primer: create trigger bi_zaposleni_fer before insert on zaposleni for each row begin declare duzina numeric; set duzina = length(new.ime); set new.plata = new.plata * duzina; end
Zadatak: • Kreirati proceduru PROSEK kojom se za određenog studenta (ulazni argument stud_ID) izračunava prosečna ocena (izlazna promenljiva prosek) • Kreirati trigger UPISPROSEKA koji se aktivira prilikom unosa novih ocena u tabeli ISPITI i upisuje prosečne ocene (koristeći proceduru prosek) u tabeli STUDENTI . Ispit Studenti
Rešenje a): -- -------------------------------------------------------------------------------- -- Routine DDL -- Note: comments before and after the routine body will not be stored by the server -- -------------------------------------------------------------------------------- DELIMITER $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `prosek`(IN stud_IDint, OUT prosek float) BEGIN /*Procedura prima ulazni argument ‘stud_ID’kojidefinisezakojegje studentapotrebnoizracunatiprosek. Izlaznompromenljivom ‘prosek’proceduravracaprosekzatrazenogstudenta. */ SELECT AVG(ocena) INTO prosek FROM ispit WHERE (broj_indeksa=stud_ID) AND (ocena<>5); /*U promenljivuprosek se upisujerezultatagregatnefunkcije AVG. Uzimamosamo one zapiseoispituzaodredjenogstudentagdeje polozio (ocenaveća od5).*/ END
Rešenje b): -- Trigger DDL Statements DELIMITER $$ USE `test`$$ CREATE DEFINER=`root`@`localhost` TRIGGER `test`.`UnesiProsek` AFTER INSERT ON `test`.`ispit` FOR EACH ROW BEGIN DECLARE stud_IDint; DECLARE prosek float; DECLARE cursor_end BOOLEAN DEFAULT false; /*Dvepomocnepromenljive. Jednazapreuzimanjestud_ID izkursora, druga u kojuce se upisatiprosek kojiizracuna procedura.*/ DECLARE cur_studenti CURSOR FOR SELECT broj_indeksa FROM studenti; -- deklaracijahendlera DECLARE continue HANDLER FOR SQLSTATE '02000' SET cursor_end = true; /*Pretpostavka je da je moguceuneti vise n-torkiodjednom padeklarisemokursorkojiceobraditijednupojednu n-torku.*/ OPEN cur_studenti; /*Popunjavamo kursor.*/ FETCH cur_studenti INTO stud_ID; /*Uzimamoprvistud_ID u promenljivustud_ID*/ WHILE (NOT cursor_end) DO /*Dokle god je uspesnopreuzetsledecizapis:*/ call prosek(stud_ID,@prosek); /*pozivaprocedurakojazadatogstudentaracunaprosek*/ UPDATE studenti SET prosek=@prosek WHERE broj_indeksa=stud_ID; /*postavljaatributprosekzatrenutnogstudentananovuvrednostkoja je izracunata u proceduri.*/ FETCH cur_studenti INTO stud_ID; /*Uzmisledecegstudentaiponovnoizvodjenjepetlje u slucajuda u kursoruimajos studenata.*/ END WHILE; CLOSE cur_studenti; /*Zatvaranje kursora.*/ END$$