【发布时间】:2019-08-01 22:55:07
【问题描述】:
给定简单的表(我使用的是 MySQL Server 8.0.17)
CREATE TABLE folders (
id varchar(3) NOT NULL,
parent varchar(3) DEFAULT NULL,
PRIMARY KEY (id),
KEY fk_folders_parent_idx (parent),
CONSTRAINT fk_folders_parent FOREIGN KEY (parent) REFERENCES folders(id) ON DELETE RESTRICT ON UPDATE RESTRICT
);
我想防止循环引用。我通过创建更新触发器来尝试此操作(因为在逐个插入项目时无法创建循环依赖项)。
DELIMITER $$
CREATE TRIGGER `test`.`folders_BEFORE_UPDATE` BEFORE UPDATE ON `folders` FOR EACH ROW
BEGIN
WITH RECURSIVE children (id) AS
(
SELECT id FROM folders WHERE parent = NEW.id
UNION ALL
SELECT f.id FROM folders f INNER JOIN children ON f.parent = children.id
)
IF NEW.parent IN children THEN
signal sqlstate '45000' set message_text = 'My Error Message'
END IF
END$$
我收到了非常有用的错误消息:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF NEW.parent IN children THEN signal sqlstate '45000' set message_text ' at line 9
我相信是因为我不能使用WITH children (...) IF NEW.parent IN children
我尝试了WITH children (...) IF EXISTS (SELECT id FROM children WHERE id = NEW.parent),但得到了相同的响应。
MySQL Workbench 告诉我,第 4 行的 BEGIN 没有 END。不过我认为这不是问题所在。
【问题讨论】:
-
我没怎么玩过 MySQL 的 CTE,但它应该让你那样使用它们吗? MySQL 通常不允许您混合查询和过程语法。你可以做一个
WITH...INSERT INTO tempTable ..... SELECT * FROM theWith然后检查 tempTable 的内容。 -
@Uueerdo 谢谢!做到了!我会尽快发布我的解决方案!