[MySQL] Trigger usuwający wszystkie wpisy


(Szymonbator) #1

Witam, chce zrobić trigger który usunie wszystkie wpisy z bazy gdy zostanie wykonany INSERT.

Dodałem taki trigger:

CREATE DEFINER=`root`@`%` TRIGGER `Wyniki`.`usun` BEFORE INSERT ON `Wyniki`.`tabele` FOR EACH ROW

BEGIN

DELETE FROM Wyniki.tabele;

END

Następnie wykonuje INSERT:

INSERT INTO Wyniki.tabele(imie,nazwisko) VALUES('Jan','Kowalski');

I otrzymuje taki błąd:

Error Code: 1442. Can't update table 'tabele' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

 

Co jest nie tak z tym trigerem?

Proszę o pomoc.


(djgrzenio) #2

moze truncate ?


(kostek135) #3

Co jest źle? Hmm obstawiam architekturę systemu. Co do samego błędu: http://dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html


(Szymonbator) #4

Próbowałem zamiast DELETE FROM Wyniki.tabele; dać TRUNCATE Wyniki.tabele;
Niestety MySQL Workbench wyrzuca taki błąd:

Operation failed: There was an error while applying the SQL script to the database.

ERROR 1422: Explicit or implicit commit is not allowed in stored function or trigger.

SQL Statement:



CREATE DEFINER=`root`@`%` TRIGGER `Wyniki`.`usun` BEFORE INSERT ON `Wyniki`.`tabele` FOR EACH ROW



BEGIN



TRUNCATE Wyniki.tabele;



END

 


(Fizyda) #5

Po co Ty chcesz coś takiego zrobić? To trochę bezsensu bo w tabeli będziesz mógł przechowywać maksymalnie jeden wiersz, a co za tym idzie jaki jest sens używać do tego bazy danych?


(Szymonbator) #6

Mam dwa skrypty PHP.

Pierwszy na początku wykonywania usuwa całą bazę danych, następnie buduje dosyć duże zapytanie INSERT które wypełnia wszystkie kolumny. Skrypt wykonuje się  co minute a jego wykonanie trwa około jednej minuty.

 

Drugi skrypt, wyświetla co ~0.10 sekund wszystkie dane z bazy.

 

Problem polega na tym, że gdy skrypt update’ujący bazę zacznie się wykonywać, to usuwa wszystko z bazy a zanim wszystko doda mija minuta.
Przez ten czas w skrypcie wyświetlającym nie jest nic wyświetlanie, bo baza jest pusta.

 

Myślę, że triger będzie lepszym rozwiązaniem, ponieważ otworzy “transakcje” usunie wszystkie wpisy, następnie doda wszystkie wpisy i zamknie “transakcje”. Czyli teoretycznie baza nie powinna być w żadnych momencie pusta.


(Fizyda) #7

Nie wiem jak Ci pomóc i co wpłynęło na taki sposób realizacji tego wszystkiego, ale dla mnie jest to wszystko już przekombinowane, a co dopiero jak dodasz triggery.

Poza tym jeśli trigger usunie zawartość tabeli a będzie dane dodawał nadal 1 minute to nic to nie da bo dane zostaną usunięta, a dopiero potem dodane. Więc tak czy siak danych nie ma przez minut.

 

Kolejna kwestia jest taka, że usuwasz całą bazę danych i pewnie tworzysz nową, więc co Ty właściwie chcesz usuwać przed dodaniem wszystkich danych skoro i tak w tej tabeli nic nie ma?

 

PS. Nie jestem pewny, ale trigger chyba wywoływany jest przy każdym insercie wiersza, a nie przy jednorazowym wysłaniu polecenia insert do serwera. Dlatego możesz mieć błąd z pierwszego posta, dodajesz dane i usuwasz to co dodajesz. Wykonywanych jest tyle operacji, że głowa mała. Dodatkowo chyba serwer dopuszcza wykonywanie równoległe poleceń insert bez blokowania danych, więc tak naprawdę w jednym czasie mogą wykonywać się równorzędnie 2 i więcej triggery które blokują tabele (ze względu na delete).


(kostek135) #8

@OP
Na triggerze tego nie zrobisz, ani pierwsze podejście z delete ani drugie z truncate - czytaj linki, które wklejają ci ludzie: http://dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html

 

Nie możesz zrobić delete, bo:
 

Nie możesz zrobić truncate, bo:
 

Zanim zaczniesz robić kolejne debilne rzeczy, przeczytaj zawartość linka.

Rozwiązanie zrób to po ludzku w transakcji: http://php.net/manual/pl/pdo.begintransaction.php