0

MySql 中的触发器有问题。

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;

notification_id在此之后,我想要一个根据该 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 ;

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

4

1 回答 1

2
  1. 我真的需要分隔符吗?

    使用您当前拥有的语法:是的,您确实需要使用默认分隔符以外的分隔符;- 否则CREATE TRIGGER语句将由关键字;before终止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语法中所述:

    OLD您可以使用别名和来引用主题表(与触发器关联的表)中的列NEWOLD.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. 但是,在这种情况下,您实际上根本不需要使用触发器(作为外键约束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 notifications_posts.id(直到列类型,包括其大小和符号)。

于 2012-08-29T15:04:47.453 回答