views:

50

answers:

3

I´m trying to create a trigger on MySQL but I´m having a syntax problem, which I was not able to find. If someone more experience could help me it would be great (it´s the first time I use MySQL!)...

The reason why I´m creating this trigger is for deleting all the orphan "labels", which has a many-to-many relation with "service_descriptor" (this two entities are linked by service_labels).

The code I have is:

CREATE TRIGGER `trg_delete_orphan_label` AFTER DELETE 
FOR EACH ROW ON `restdb`.`service_labels`  
  DELETE FROM `restdb`.`labels`
   WHERE EXISTS (SELECT *
                   FROM old D 
              LEFT_JOIN `restdb`.`service_labels` SL ON SL.`id_label` = D.`id_label` 
                                                    AND D.`id_service` = SL.`id_service`
                  WHERE SL.`id_label` IS NULL
                        `restdb`.`labels`.`id` = D.SL.`id_label`); 

Thanks in advance !

+1  A: 

You have missed AND

Try this code

CREATE TRIGGER `trg_delete_orphan_label` AFTER DELETE FOR EACH ROW ON `restdb`.`service_labels`   
    DELETE 
    FROM 
        `restdb`.`labels` 
    WHERE 
        EXISTS (SELECT 
                    * 
                FROM 
                    old D LEFT_JOIN 
                    `restdb`.`service_labels` SL ON 
                        SL.`id_label` = D.`id_label` AND 
                        D.`id_service` = SL.`id_service` 
                WHERE 
                    SL.`id_label` IS NULL AND
                    `restdb`.`labels`.`id` = D.SL.`id_label`                         
                    );  
Madhivanan
I´ve added an and. It still with some syntax problem, though...Thanks for your support !
Alucard
+1  A: 

There are a couple of problems with your trigger, most notably the placement of "FOR EACH ROW", and the way you are treating OLD like a table, when it's really just a row.

This should work for you:

DROP TRIGGER IF EXISTS `trg_delete_orphan_label`;

CREATE TRIGGER `trg_delete_orphan_label` AFTER DELETE ON `service_labels` 
FOR EACH ROW
    DELETE FROM `labels`
    WHERE `id` = OLD.`id_label`
    AND NOT EXISTS (
        SELECT NULL
        FROM `service_labels` SL 
        WHERE SL.`id_label` = `labels`.`id`                        
    );                     
Ike Walker
A: 

Thanks everyone ... I´ve finaly solved it because of your help...

In the end the work is:

CREATE TRIGGER trg_delete_orphan_label AFTER DELETE ON restdb.service_descriptor
FOR EACH ROW DELETE FROM restdb.labels WHERE id NOT IN ( SELECT restdb.service_labels.id_label FROM restdb.service_labels );

Alucard
I'm glad you found something that works, although I notice that the trigger is on a different table now. Your solution is slightly different from mine both functionally and from a performance standpoint. Your trigger is deleting ALL orphans, whereas mine only deletes newly orphaned rows. My approach will also be faster, so you may want to consider it.
Ike Walker
Yes! It's truth... the problem is that it didn't work when the trigger was on service_labels table, even though the deleting statement works well for the orphan ones... it's because the service_labes table was not being deleted directly... it was being deleted by cacade after service_descriptor...For that reason I've changed the table and because of that I had to change the logic as well!
Alucard