我在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 ;
我的语法是否正确?我真的需要分隔符吗?
答案 0 :(得分:2)
我真的需要分隔符吗?
使用当前的语法:是的,您需要使用默认;
以外的分隔符 - 否则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
语句终止的位置。
我的语法是否正确?
几乎,但不完全。您应该使用THAT_ID_TO_DELETE
而不是OLD.post_id
。如CREATE TRIGGER
Syntax中所述:
您可以使用别名
OLD
和NEW
来引用主题表(与触发器关联的表)中的列。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;
但是,在这种情况下,您根本不需要使用触发器(因为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}}必须有匹配的记录(下至列类型,包括其大小和符号)。