我在创建BEFORE INSERT触发器时遇到问题。
表架构:
CREATE TABLE IF NOT EXISTS `myReferenceTable` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`linkFrom` bigint(20) NOT NULL,
`linkTo` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `linkFrom` (`linkFrom`,`linkTo`),
KEY `linkTo` (`linkTo`)
) ENGINE=InnoDB
插入数据:
INSERT INTO `myReferenceTable` (`id`, `linkFrom`, `linkTo`) VALUES
(1, 1, 2), // allowed
(2, 2, 1); // allowed
我尝试创建BEFORE INSERT触发器失败,导致linkFrom
和linkTo
不相等。这篇表格文章参考表不能有任何引用它的文章,
/* This fails */
create trigger myReferenceTable_noDuplicate
BEFORE INSERT
ON myReferenceTable
FOR EACH ROW
BEGIN
IF NEW.linkFrom = NEW.linkTo
insert ignore()
END IF;
END;
示例:
INSERT INTO `myReferenceTable` (`id`, `linkFrom`, `linkTo`) VALUES
(3, 1, 1), // should fail
(4, 2, 2); // should fail
不允许上述数据。所以我希望这个表是一个“set”表,允许以下数据:
INSERT INTO `myReferenceTable` (`id`, `linkFrom`, `linkTo`) VALUES
(3, 1, 2), // allowed
(4, 1, 3); // allowed
答案 0 :(得分:2)
触发器用于数据完整性并避免数据。使用触发器删除两个以上的表。在初始化触发器之前,我们暂时更改mysql分隔符操作符。因为触发器对多个sql命令使用分号(;)运算符。
在您的情况下,逐个使用以下命令:
第1步:
更改分隔符,
delimiter $$
第2步:
创建触发器,
CREATE TRIGGER `blog_before_delete`
AFTER DELETE ON `blog`
FOR EACH ROW
BEGIN
DELETE FROM blog_tags where blogid = OLD.id;
DELETE FROM blog_comments where blogid = OLD.id;
END
$$
第3步:
恢复分隔符,
delimiter ;
说明:
这里OLD是一个关键字,指的是我们需要删除的博客表行。每当我们删除博客表中的条目时,Mysql就会启动触发器blogbeforedelete。删除与博客相关的所有标签,并删除与博客相关的所有评论。这可确保数据库中不存在不需要的数据。这个过程也是自动的。
(source)
答案 1 :(得分:1)
INSERT ignore()不会取消插入或导致插入失败。有几种方法可以做到这一点,但最简单的方法是导致错误:
...
IF NEW.linkFrom = NEW.linkTo
DECLARE dummy INT;
SELECT LINKFROM_EQUALS_LINKTO INTO dummy FROM links
WHERE links.id = new.id;
END IF;
...