Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Triggery (wyzwalacze)
Forum PHP.pl > Forum > Bazy danych > MySQL
djgrin
Czesc!
Wytlumacze swoj problem na przykladzie: mam tabele z danymi pracownikow oraz z urlopami, ktore biora pracownicy. Napisalem sobie triggera, ktory po dodaniu czegos do tabeli Urlopy (after insert), odejmuje ilosc pozostalego urlopu dla danego pracownika z tabeli Pracownicy. Tyle, ze dziala on w ten sposob, ze mozna dodawac urlopy w nieskonczonosc, czyli powodowac ujemne wartosci w polu IloscUrlopu w tabeli Pracownicy. Chcialbym to zmienic - mam dwa pomysly: pierwszy jest taki, ze w triggerze, ktory napisalem uwarunkuje wykonanie sie wszystkiego od zawartosci pola IloscUrlopu w tabeli Pracownicy dla danego pracownika, a drugi taki, ze napisze nowego triggera "before update on Pracownicy", ktory sprawdzi wartosc pola IloscUrlopu danego pracownika i jesli bedzie za mala, to przerwie zmiane wartosci (+ np. usunie wpis z tabeli Urlopy).
Jak sadzicie, ktora opcja jest lepsza (chyba, ze macie jakies inne pomysly) i jak takie cos napisac?
Prosze o szybka odpowiedz, dzieki z gory.
prond
Moim zdaniem trigger najlepiej pasuje przypiąć do tabeli urlopy, przed insertem.
Sprawdzasz wtedy w tabelce pracownicy, czy pracownik ma jeszcze dostatecznie duzo dni urlopu.
Jak nie ma to anulujesz inserta - to jest lepsze niz kasowanie (o ktorym napisales) poniewaz informujesz aplikacje, ze nie dalo sie dodac urlopu.
djgrin
No zgadza sie, jest to lepsze rozwiazanie (pisalem tego posta bardzo szybko i teraz widze, ze odbilo sie to na jakosci mojej wypowiedzi winksmiley.jpg). W kazdym razie - jak takiego inserta anulowac w triggerze? Domyslam sie, ze chodzi o anulowanie transakcji, ale gdybym zobaczyl to na jakims przykladzie, bylbym bardzo wdzieczny winksmiley.jpg.
Dzieki za odpowiedz winksmiley.jpg
SongoQ
Nie przygladalem sie triggerom w MySQLu ale adektwanie bedzie jak w innych bazach, wystarczy ze zwrocisz false, null w triggerze i rekord nie zostanie dodany, jesli zwracasz NEW czy OLD to operacja dochodzi do skutku.
djgrin
Ok, wymyslilem to czego szukalem. Okazalo sie, ze jedynym sposobem na anulowanie transakcji w triggerze jest spowodowanie jakiegos bledu, np. odwolanie sie do nieistniejacej kolumny w tabeli (tabela musi istniec, inaczej blad bedzie za kazdym razem wyskakiwal). Wykorzystalem przy tym fakt, ze w komunikacie o bledzie pojawi sie nazwa tej kolumny, a moj trigger prezentuje sie nastepujaco:

  1. delimiter |
  2. CREATE TRIGGER tgr_urlopy
  3. after INSERT ON urlopy
  4. FOR each row
  5. begin declare zmienna INT;
  6. IF (SELECT IloscUrlopu FROM umprac WHERE IdUmowa=new.IdUmowa)>=(datediff(new.OkresDo, new.OkresOd)+1) then
  7. IF new.IdUrlopu='01' then
  8. UPDATE umprac SET IloscUrlopu=IloscUrlopu-datediff(new.OkresDo, new.OkresOd)-1 WHERE IdUmowa=new.IdUmowa;
  9. end IF;
  10. else SELECT `Pracownik posiada za malo urlopu!` FROM kadry INTO zmienna; end IF;
  11. end;|

Coz, mam nadzieje, ze komus to sie przyda winksmiley.jpg...
Pozdrawiam.
SongoQ
Sprawdz to co pisalem wczesniej. Jesli stosujesz trigger przed dodaniem rekordu i z triggera zamiast return NEW zwrocisz false czy doda rekord. Jesli takie cos zadziala to problem masz rozwiazany i nie trzeba z bledem kombinowac.

Sprawdz to niestety w manualu czegos takiego sie nie doszukalem co w cale nie jest powiedziane ze nie istnieje.
djgrin
Niestety trzeba "kombinowac z bledem", bo nie ma czegos takiego jak "return new", czy "return" w ogole w triggerach w tym systemie (stad te braki w manualu). A pomysl z bledem nie jest niestety moj:
http://www.brokenbuild.com/blog/2006/08/15...with-a-trigger/

Pozdrawiam.
SongoQ
Dobrze wiedziec na przyszlosc. Pewnie kiedys wprowadza.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.