gpt4 book ai didi

MySQL:自定义行验证

转载 作者:行者123 更新时间:2023-11-29 13:49:31 25 4
gpt4 key购买 nike

我有这样的例子:

CREATE TABLE a(
id INT PRIMARY KEY AUTO_INCREMENT,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES a(id)
);

DELIMITER ;;

CREATE TRIGGER a_insert BEFORE INSERT ON a
FOR EACH ROW
BEGIN
SIGNAL SQLSTATE '01431' SET MESSAGE_TEXT = 'The foreign data source you are trying to reference does not exist.';
END;;

DELIMITER ;


INSERT INTO a(parent_id) VALUES (NULL);
INSERT INTO a(parent_id) VALUES (1);
INSERT INTO a(parent_id) VALUES (2);
INSERT INTO a(parent_id) VALUES (4);
INSERT INTO a(parent_id) VALUES (999);

SELECT * FROM a

最终得到 4 条记录:

----------------
id parent_id
----------------
1 NULL
2 1
3 2
4 4

我发现网上有帖子说MySQL不支持触发器回滚。这是一个问题,因为我想要这样的层次结构,其中没有行指向它自己,并且像 ID=4 那样插入可以正常工作。如何确保数据库中没有此类记录?

最佳答案

嗯,问题出在 auto_increment 上,因为在 BEFORE INSERT 事件中,您还没有分配该值。另一方面,在 AFTER INSERT 事件中,您无法对其执行任何操作。

如果您想使用auto_increment id 列,可能的解决方案是使用单独的表进行排序。

你的架构看起来像

CREATE TABLE a_seq(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE a(
id INT NOT NULL PRIMARY KEY DEFAULT 0,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES a(id)
);

还有你的触发器

DELIMITER $$
CREATE TRIGGER a_insert
BEFORE INSERT ON a
FOR EACH ROW
BEGIN
INSERT INTO a_seq VALUES(NULL);
SET NEW.id = LAST_INSERT_ID();
IF NEW.id = NEW.parent_id THEN
SET NEW.id = NULL;
END IF;
END$$
DELIMITER ;

如果id=parent_id触发器故意违反分配NULL值的NOT NULL约束。因此这条记录不会被插入。

这里是SQLFiddle演示。取消注释最后一个插入语句。它不允许您进行此类插入。

关于MySQL:自定义行验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16876852/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com