简单的TRIGGER,它根据查询删除特定记录

时间:2012-08-29 11:59:52

标签: mysql sql

我在MySql中遇到TRIGGER问题。

notifications_posts
notification_id from_user   on_post_id  in_group_id date
2   1   162 3   2012-07-11 12:01:08
3   19  163 1   2012-07-11 12:03:26
4   19  164 1   2012-08-10 17:42:36
5   1   165 3   2012-08-29 12:14:01
6   1   165 3   2012-08-29 12:14:29
11  1   2   3   2012-08-29 14:38:42

有时我需要删除帖子,例如使用以下命令:

DELETE FROM posts WHERE posts.post_id = 165;

在此之后,我想要一个TRIGGER,根据该ID删除notification_id中的所有记录。

这是我到目前为止所做的:

DELIMITER $$
CREATE OR REPLACE TRIGGER CleanNotificationPosts
AFTER DELETE ON posts
FOR EACH ROW
BEGIN
    DELETE FROM notifications_posts WHERE notifications_posts.id = THAT_ID_TO_DELETE;
END $$
DELIMITER ;

我的语法是否正确?我真的需要分隔符吗?

1 个答案:

答案 0 :(得分:2)

  1.   

    我真的需要分隔符吗?

    使用当前的语法:是的,您需要使用默认;以外的分隔符 - 否则CREATE TRIGGER语句将由;终止END关键字,这将导致解析错误(因为BEGIN ... END块不会被终止)。

    但是,由于该块中只有一个语句,实际上根本不需要使用BEGIN ... END

    CREATE OR REPLACE TRIGGER CleanNotificationPosts
    AFTER DELETE ON posts
    FOR EACH ROW
    DELETE FROM notifications_posts WHERE notifications_posts.id = THAT_ID_TO_DELETE;
    

    在这种情况下,不需要更改语句分隔符:;确实是CREATE TRIGGER语句终止的位置。

  2.   

    我的语法是否正确?

    几乎,但不完全。您应该使用THAT_ID_TO_DELETE而不是OLD.post_id。如CREATE TRIGGER Syntax中所述:

      

    您可以使用别名OLDNEW来引用主题表(与触发器关联的表)中的列。 OLD.col_name在更新或删除之前引用现有行的列。 NEW.col_name指的是要插入的新行的列或更新后的现有行。

    此外,OR REPLACE在MySQL中无效。在执行DROP TRIGGER IF EXISTS声明之前,您可以改为CREATE TRIGGER

    因此:

    DROP TRIGGER IF EXISTS CleanNotificationPosts;
    CREATE TRIGGER CleanNotificationPosts
    AFTER DELETE ON posts
    FOR EACH ROW
    DELETE FROM notifications_posts WHERE notifications_posts.id = OLD.post_id;
    
  3. 但是,在这种情况下,您根本不需要使用触发器(因为foreign key constraint ON DELETE CASCADE就足够了):

    ALTER TABLE notifications_posts
      ADD FOREIGN KEY (id) REFERENCES posts (post_id) ON DELETE CASCADE;
    

    请注意以下先决条件以添加此类外键约束:

    • 两个表都必须使用InnoDB存储引擎;

    • posts表中必须有一个索引post_id是第一列;以及

    • 所有非posts.post_id NULL的{​​{1}}必须有匹配的记录(下至列类型,包括其大小和符号)。