Jump to content
php.lv forumi

Trigeris priekš dzēšanas


maarc93

Recommended Posts

Ir izveidots trigeris, kam vajadzētu izdzēst ierakstus no citām tabulām, kur arī ir tāds pats ID_rezervacija:

DELIMITER //
CREATE TRIGGER dzestRez
BEFORE DELETE ON rezervacijas
FOR EACH ROW
BEGIN
	DELETE FROM atsauksmes WHERE ID_rezervacija=ID_rezervacija;
	DELETE FROM rezervacija_has_serviss WHERE ID_rezervacija=ID_rezervacija;
	DELETE FROM rezervacija_has_istaba WHERE ID_rezervacija=ID_rezervacija;
	DELETE FROM maksajumi WHERE ID_rezervacija=ID_rezervacija;
END //
DELIMITER ;

bet trigerim izpildoties, tiek dzēsts viss tabulas saturs. Kas nav pareizi?

Link to comment
Share on other sites

Ir izveidots trigeris, kam vajadzētu izdzēst ierakstus no citām tabulām, kur arī ir tāds pats ID_rezervacija:

DELIMITER //
CREATE TRIGGER dzestRez
BEFORE DELETE ON rezervacijas
FOR EACH ROW
BEGIN
	DELETE FROM atsauksmes WHERE ID_rezervacija=old.ID_rezervacija;
	DELETE FROM rezervacija_has_serviss WHERE ID_rezervacija=old.ID_rezervacija;
	DELETE FROM rezervacija_has_istaba WHERE ID_rezervacija=old.ID_rezervacija;
	DELETE FROM maksajumi WHERE ID_rezervacija=old.ID_rezervacija;
END //
DELIMITER ;

Jāizmanto old.ID_rezervacija.

Link to comment
Share on other sites

rāda šādu erroru, kad dzēšu ierakstu:

#1451 - Cannot delete or update a parent row: a foreign key constraint fails (`viesnica`.`rezervacija_has_serviss`, CONSTRAINT `ID_rezervacija` FOREIGN KEY (`ID_rezervacija`) REFERENCES `rezervacijas` (`ID_rezervacija`) ON DELETE NO ACTION ON UPDATE NO ACTION) 

 

šādi izskatās trigeris:

1XjoQqaYMjIkIiXW1Z7fy2f8HK20.png

Edited by maarc93
Link to comment
Share on other sites

bet kā lai tagad dara lietotāju dzēšanu? ir šāds trigeris. esmu ticis tik tālu, bet tik un tā nestrādā...

DELIMITER //
CREATE TRIGGER dzestLiet
BEFORE DELETE ON lietotaji
FOR EACH ROW
BEGIN
	DECLARE @ID AS INT;
	SET @ID = (SELECT ID_rezervacija FROM rezervacijas WHERE ID_lietotajs=old.ID_lietotajs);
	
	DELETE FROM klienti WHERE ID_lietotajs=old.ID_lietotajs;
	DELETE FROM rezervacijas WHERE ID_lietotajs=old.ID_lietotajs;
	DELETE FROM atsauksmes WHERE ID_rezervacija=@ID;
	DELETE FROM rezervacija_has_serviss WHERE ID_rezervacija=@ID;
	DELETE FROM rezervacija_has_istaba WHERE ID_rezervacija=@ID;
	DELETE FROM maksajumi WHERE ID_rezervacija=@ID;
END //
DELIMITER ;
Edited by maarc93
Link to comment
Share on other sites

 

bet kā lai tagad dara lietotāju dzēšanu? ir šāds trigeris. esmu ticis tik tālu, bet tik un tā nestrādā...

DELIMITER //
CREATE TRIGGER dzestLiet
BEFORE DELETE ON lietotaji
FOR EACH ROW
BEGIN
	DECLARE @ID AS INT;
	SET @ID = (SELECT ID_rezervacija FROM rezervacijas WHERE ID_lietotajs=old.ID_lietotajs);
	
	DELETE FROM klienti WHERE ID_lietotajs=old.ID_lietotajs;
	DELETE FROM rezervacijas WHERE ID_lietotajs=old.ID_lietotajs;
	DELETE FROM atsauksmes WHERE ID_rezervacija=@ID;
	DELETE FROM rezervacija_has_serviss WHERE ID_rezervacija=@ID;
	DELETE FROM rezervacija_has_istaba WHERE ID_rezervacija=@ID;
	DELETE FROM maksajumi WHERE ID_rezervacija=@ID;
END //
DELIMITER ;

Izskatās, ka ir reference no tabulas viesnīca uz tabulu rezervacija. varianti:

  • jadzēš viesnīcas pie reizes
  • nekorekta refernce
Link to comment
Share on other sites

Ja lieto Foreign Keyus, tad ir svarīgi vai tie ir pareizi/loģiski un kādā secībā dzēš ierakstus t.i. ar 'NO ACTION' nevar dzēst no parent tabulas ierakstu, kam ir reference child tabulā.

 

Šajā gadījumā kļuda "#1451 - Cannot delete or update a parent row: a foreign key constraint fails (`viesnica`.`rezervacija_has_serviss`, CONSTRAINT `ID_rezervacija` FOREIGN KEY (`ID_rezervacija`) REFERENCES `rezervacijas` (`ID_rezervacija`) ON DELETE NO ACTION ON UPDATE NO ACTION) " norāda, ka nevar dzēst ierakstu no Rezervacijas tabulas, jo uz to referencējas rezervacija_has_serviss tabula.

 

Teorētiski samainot (uzliekot virspusē kā pirmo) dzēšanu no rezervacija_has_serviss varētu palīdzēt konkrētajai lietai (un tā izkārtot arī visas pārējās tabulas (pēc ERD shēmas) - sākot no "tālākās" līdz vidējai jebšu centrālajai) 

 

 

No otras puses, ja jau ir nepieciešama šāda veida dzēšana no visurienes/visām tabulām (un vēlme lietot FK), tad, manuprāt, ir jēga ON DELETE darbību nomainīt no NO ACTION uz CASCADE  ( http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html ) un tad dzēšot no "master" (šajā gadījumā Lietotaji) tabulas ierakstu visiem referencētajiem ID būtu jāizdzēšas automātiski pašiem, bez nepieciešamības lietot trigeri (ekspirementiem var pamēģināt arī SET NULL, tas nedzēsīs ierakstu, bet nomainīs attiecīgos id, lai saprastu vai viss notiek korekti).

 

 

 

 

Personīgi, gan škiet, ka FK ir diezgan liela sāpe (uz visiem jābūt indeksi, vienādas storage engīnes, nevar būt partīcijas utt) un izprotamāka (db) loģika ir vai nu aplikācijas pusē vai plikos triggeros.

Tāpat arī FK Cascade dzēšanas neaktivizē aiztikto tabulu trigerus t.i. nav iespējama kaut kāda atdalīta ON DELETE loģika pašai tabulai utt.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...