【发布时间】:2014-08-23 18:33:06
【问题描述】:
CREATE TABLE parent (
parent_id VARCHAR(255) PRIMARY KEY
);
CREATE TABLE child (
parent_id VARCHAR(255) REFERENCES parent ON DELETE CASCADE,
child_id VARCHAR(255) PRIMARY KEY
);
CREATE OR REPLACE FUNCTION delete_parent()
RETURNS TRIGGER AS $$
BEGIN
DELETE FROM parent WHERE parent_id = OLD.parent_id;
RETURN NULL;
END; $$ LANGUAGE 'plpgsql';
CREATE TRIGGER delete_parent AFTER DELETE
ON child
FOR EACH ROW
EXECUTE PROCEDURE delete_parent();
错误:
stack depth limit exceeded
提示:'在确保平台的堆栈深度限制足够之后,增加配置参数“max_stack_depth”(当前为 6144kB)。'
背景:
- 一个
parent可以有多个children - 该架构设计为,如果
parent被删除,它的所有子记录也会被删除。 - 如果删除了
child,触发器将删除parent,然后级联删除与该parent相关的所有其他children
这已经工作了几个月,今天突然我们开始收到这个错误。
我找不到可能存在无限递归的情况,我正在考虑将堆栈深度限制加倍以查看会发生什么。
注意:实际的架构比这更复杂,并且有更多的相关表具有 CASCADE 删除约束。但这是唯一的触发因素。
更新:所以我将 max_stack_depth 限制加倍,现在可以了。我认为这不是一个好的解决方案,我仍然不确定如何防止这种情况在未来发生。
【问题讨论】:
-
通过 child->parent FK 的级联删除将导致如果删除父级,则所有子级都将被删除。你的触发器正好相反。所以一旦一个孩子被删除,它的父母和它的兄弟姐妹就会被删除。这是你的意图吗?
-
没错。如果孩子被删除,请删除父母及其所有 silbings
-
顺便说一句:你为什么使用 varchar(255) 字段作为 PK 和 FK ?
-
它实际上不是 VARCHAR(255)。服务器现在着火了,所以我只是快速编写了一个人为的示例,而不是复制真实的模式。它是一个 UUID。
标签: postgresql