címkék

beleszóltak

amik jók

Ricsi megmondja:
java'nother blog

Ebben hiszek:
BMWfanatics.hu

Triggerek, tárolt eljárások, függvények MySQL-ben 1.

2009.03.06. 00:08 nullstring

Ha már szóba került a trigger mint olyan a jabber-es bejegyzésem kapcsán, úgy döntöttem, hogy leírom mi is az valójában, mert nagyon sokan nincsenek vele tisztában, vagy nem igazán tudják mi fán terem. Ugyan ez igaz a tárolt eljárásokra és a függvényekre is.

Először a triggerekről ejtenék pár szót, ami reményeim szerint bőven elég lesz ahhoz, hogy ha valaki akar, el tudjon indulni a MySQL ezen szolgáltatásának nem éppen rögös útján is.

A triggerek valójában eljárások, melyek egy bizonyos táblához vannak kapcsolva, és valamilyen esemény (DML utasítások esetén: insert, update, delete) hatására futnak le. Ezen túlmenően megszabhatjuk azt is, hogy pontosan mikor. Az esemény előtt vagy után.

before insert, after insert, before update, after update, before delete, after delete

azaz

beszúrás előtt, beszúrás után, frissítés előtt, frissítés után, törlés előtt, törlés után

Azt tudni kell, hogy egy eseményhez nem kapcsolhatunk több ugyan arra az eseményre (INSERT, UPDATE, DELETE), ugyan abban az időben (BEFORE, AFTER) aktiválódó triggert. Ez azt jelenti, hogy nem lehet két BEFORE UPDATE triggered egy táblára, de lehet egy BEFORE UPDATE és AFTER UPDATE, illetőleg az is rendben van, ha BEFORE INSERT és BEFORE UPDATE eseményre állítasz be triggereket. Az is kikötés, hogy átmeneti táblákhoz és nézetekhez sem kapcsolhatunk triggert, továbbá a triggerek nem módosíthatják azokat a táblákat, amikhez kapcsolva vannak. Tehát, ha a users tábla beszúrás utáni eseményére lefut egy trigger, az nem szúrhat be, nem frissíthet adatot, és nem végezhet törlést a users táblán.

Fontos, hogy a DELETE esemény nem fedi le a DROP TABLE és a TRUNCATE parancsokat. Tehát ha eldobod a táblát, vagy kiüríted, a triggered nem fogja törlésnek venni az eseményt, és nem fog lefutni.

Jelenleg a triggerek idegen kulcsok (foreign keys) által kiváltott eseményekre nem reagálnak. Tehát hiába törlődik egy rekordod az idegen kulcsok által másik táblából való törlés hatására, a triggered nem fogja törlésnek tekinteni. Reméljük, ezt mihamarabb javítják.

Triggerek létrehozása... lássunk rá egy példát:

Van egy orders táblánk, amiben van egy elsődleges auto_increment id-nk, és egy product_id mezőnk, ami a products tábla szintén auto_increment id mezőjéhez van kapcsolva. A products táblában van továbbá egy amount mező, ami a termék még raktáron lévő mennyiségét jelöli:

create table products (
	id int not null auto_increment,
	amount not null default 1,
	primary key (id)
);

create table orders (
	id int not null auto_increment,
	product_id not null,
	amount not null default 1,
	primary key (id)
);

Szeretnénk, hogy amikor az orders táblába bekerül egy új sor, tehát az egyik termékből vásárolnak x darabot, akkor a products táblában a termék mennyisége x-el csökkenjen.
Ezt triggerrel egyszerűen a következő módon tehetjük meg:
 

DELIMITER //
CREATE TRIGGER update_product_amount BEFORE INSERT ON `orders`
FOR EACH ROW
BEGIN
	UPDATE `products`
	SET amount = amount - NEW.amount
	WHERE id = NEW.product_id;
END;
DELIMITER ;

Látható, hogy nagyon egyszerűen pár sor segítségével megoldható a dolog, így nem kell PHP-ból plusz lekérdezést küldenünk a MySQL felé, ami ugye nekünk is jó, és a szervernek is.

Tehát a trigger létrehozásának formája:
CREATE TRIGGER trigger_neve esemény ON táblanév
FOR EACH ROW
BEGIN
    utasítások
END;

ahol az esemény a fent felsorolt események valamelyike, a táblanév pedig annak a táblának a neve, amelyiknek a változásait/eseményeit "figyeltetni" szeretnénk a triggerrel.
A "FOR EACH ROW" azt jelzi, hogy az utasítások minden alkalommal fussanak le, mikor a trigger aktiválódik. A BEGIN és az END csak akkor szükséges, amennyiben bonyolultabb utasításokat szeretnénk írni a trigger végrehajtó részébe.

A NEW mellé tartozik természetesen egy OLD is. Ha valaki még nem találta volna ki, ez azt jelzi, hogy az újonnan beszúrt sorra vonatkozik, illetőleg a ponttal mögötte álló mezőre. Ebből fakadóan értelemszerű, hogy beszúrás esetén nem használható az OLD kulcsszó, illetőleg törlés esetén nem elérhető a NEW. A NEW által elért mezőket megváltoztathatjuk, míg az OLD által elérhetőek csak olvashatóak, de remélem ez utóbbit nem kell elmagyaráznom, hogy miért van így :D

A NEW által elérhető mezők módosítása.... pl. beszúrásnál, ha azt szeretnénk, hogy a users táblába beszúrt nevek csupa kisbetűvel legyenek írva.:

DELIMITER //
CREATE TRIGGER lowercase_username BEFORE INSERT ON `users`
FOR EACH ROW SET NEW.`username` = lower(NEW.`username`);
DELIMITER ;

És ez legyen egyben példa arra is, mikor nem használjuk a BEGIN és az END kulcsszavakat :)

A már léterhozott triggereinket a

SHOW triggers;

parancs segítségével listázhatjuk, illetőleg a

DROP TRIGGER trigger_neve;

paranccsal törölhetjük.

Triggereink sajnos nem tartalmazhatnak olyan utasításokat, amik explicit vagy implicit módon indítanak vagy állítanak le tranzakciókat (START TRANSACTION, COMMIT, ROLLBACK).

Zárszó gyanánt megjegyezném, hogy amennyiben csillapíthatatlan vágyat érzel, hogy többet tudjál meg a témában, semmi esetre se vedd meg az elábbi könyvet:

Jenei Imre
Triggerek, tárolt eljárások és függvények alkalmazása MySOL-ben

Ugyanis a szerző, mindösszesen 20 oldalt szánt a témára, a maradék 200 oldalt pedig a tartalomjegyzék, a bevezető, a MySQL telepítése windows alatt képekkel (minden next gombnyomás külön screenshot), több 10 oldal CSS, Javascript, HTML, Delphi és némi PHP teszi ki. Én megvettem, nagyon mérges vagyok... Bevallom, ez a csalódás is motivált, mikor megírtam ezt a postot. Lényeg: inkább böngészd a dev.mysql.com címet..

Mára ennyi, majd jön a tárolt eljárások és a függvények... majd.. :)
Ha kérdés van, írd meg bátran, lehet, hogy itt-ott nem voltam túl egyértelmű :)

3 komment

Címkék: tutorial howto mysql triggerek tárolt eljárások

A bejegyzés trackback címe:

https://nullstring.blog.hu/api/trackback/id/tr41984424

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

I_Isti 2009.03.18. 21:06:06

Köszönet & örök hála a posztért.

CounterS 2011.04.12. 21:25:12

Nagyon jó leírás, köszi. :))

Triest 2012.03.02. 17:53:04

Köszi, pont ilyen rövid tömör és lényegre törő leírást kerestem.



süti beállítások módosítása