[ Tyler Durden @ 29.07.2010. 12:07 ] @
ERROR 1442 (HY000): Can't update table 'neka_tabela' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

ovu gresku dobijem pokusam insert na tabelu za koju sam napravio ovaj trigger.

Code (sql):

DELIMITER //
CREATE TRIGGER sesija AFTER INSERT ON neka_tabela
FOR EACH ROW
BEGIN
DECLARE noos INTEGER;
SELECT COUNT(0) INTO noos FROM neka_tabela WHERE par uslova... AND username = NEW.username GROUP BY NEW.username;
IF noos > 1 THEN
UPDATE neka_tabela SET pa par kolona ... WHERE username = NEW.username;
END IF;
END; //
DELIMITER ;
 


Na netu vidjeh da spominju kako ovo ne moze da se uradi ovako, ali nije mi jasno zasto.
[ deerbeer @ 29.07.2010. 12:38 ] @
Izgleda kao da se isti trigger ponovo okida na update statement , iako si eksplicitno stavio AFTER INSERT .
[ djoka_l @ 29.07.2010. 12:40 ] @
Koliko sam video, na netu ima nekoliko predloženih rešenja:

1. ako treba da se promene neke vrednosti nad slogom koji je tekući, to se radi direktno dodelom NEW.polje varijablama.
2. ako 1. nije rešenje to se odradi procedurom
3. redizajn baze.

Meni se čini da je 3. tvoja opcija. Malo mi je čudno da neki slogovi u jednoj tabeli zavise od toga koliko ima slogova sa nekim uslovom u toj istoj tabeli. Hmmm...
[ Tyler Durden @ 29.07.2010. 12:59 ] @
Da malo pojasnim, sigurno ima i drugih rijesenja pa da vidimo, ali ovo mi je nekako najelegantnije.
U sustini ja sam ovo vec sredio sa jednom skriptom koja to cisti, ali sad bih to malo "finije" da odradim.

Radi se o tabeli koja cuva neke korisnicke sesije i ponekad se desi da se odredjena sesija ne "zatvori". Ovaj trigger treba to da zatvori, onda kad se startuje nova sesija za tog korisnika.
Dakle, za svaki insert treba da se odradi update za neki red iznad u slucaju da je ovaj noos veci od 1 (taj upit sa noos-om mi pokazuje da li ima ili nema nezatvorenih sesija).
[ djoka_l @ 29.07.2010. 13:10 ] @
Ha, ja sam pokušavao sa dokučim šta je to noos (jedino mi je palo na pamet "Number of operating systems").

Imao sam sličan slučaj, da želim da "ubijem" neaktivnu Oracle sesiju, ako se pojavi duplikat usera na bazi. Moje rešenje je bilo da procedura za login proveri da li postoji sesija, ako postoji, pita usera da li želi da je ubije i ako odgovori potvrdno, ubije staru sesiju i upiše podatak o novoj sesiji. U suprotnom ne dozvoli dalji rad (ideja je bila da se spreči deljenje naloga između korisnika, tj. da se dopusti da jedan korisnik ima samo jednu aktivnu sesiju).

U tvom slučaju, mislim da je potrebna procedura (naravno, ako ti nije potrebno pitanje, samo ažuriraj podatke o prethodnoj sesiji i onda uradi insert).
[ Tyler Durden @ 29.07.2010. 13:21 ] @
Ono sto sam na netu naletio jeste da ostale baze ovo podrzavaju, jedino jos MySQL nije implementirao.
A neki lik se zalio i za proceduru da mu je opet istu gresku vracalo i zato me malo mrzi da probavam.

Kako onda tu proceduru da pozivam/uglavim? Da napravim trigger koji ce samo da poziva proceduru za svaki INSERT, a procedura ce da odradjuje sav posao?
[ djoka_l @ 29.07.2010. 13:26 ] @
Yup, pozoveš proceduru, a ona uradi proveru, update ako treba, pa onda insert.

Inače, malo je problematično kontrolisati integritet kada dopustiš trigere. Verovatno im se nije dalo da do kraja implementiraju mehanizam. Inače, i Oracle ne dozvoljava de se, recim radi INSERT u ON INSERT trigeru. Kada bi to dozvolili, verovatno bi 90% prvih verzija trigera pravilo neku beskonačnu rekurziju.
[ Tyler Durden @ 29.07.2010. 13:37 ] @
Ok, to je jasno da bi INSERT u ON INSERT pravio problem, ali ovo je update/insert koji nisu nikako direktno povezani :-/

Sad cu malo da pogledam oko procedura....
[ Tyler Durden @ 29.07.2010. 15:47 ] @
Hm, da.
Napravio sam proceduru koja radi kako treba, ali kad pokusam da napravim trigger koji ce da izvrsava tu proceduru dobijem gresku:

ERROR 1235 (42000): This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'

Ovako izgleda trigger:
Code (sql):

CREATE TRIGGER clear_session AFTER INSERT ON neka_tabela
FOR EACH ROW
BEGIN
CALL clear_sessions('NEW.username',@a);
END; //

i tako sipak na kraju.
Nista, bar sam malo naucio procedure i triggere... :-)