gpt4 book ai didi

postgresql - 如何在 View 上编写删除规则?

转载 作者:行者123 更新时间:2023-11-29 11:28:44 24 4
gpt4 key购买 nike

我正在尝试在 View 上编写一条规则以从组件表中删除元组,但到目前为止只能从其中一个表中删除数据。我已经使用带有基本 View 的 postgres 一段时间了,但是我对 View 规则没有任何经验。

我写了一个愚蠢的小测试用例来找出/显示我的问题。在这个例子中每个子元组只有一个父元组(我的实际模式当然不是这样的)。

组件表:

CREATE TABLE parent(
id serial PRIMARY KEY,
p_data integer NOT NULL UNIQUE
);
CREATE TABLE child(
id serial PRIMARY KEY,
parent_id integer NOT NULL UNIQUE REFERENCES parent(id),
c_data integer NOT NULL
);

查看:

CREATE TABLE child_view(
id integer,
p_data integer,
c_data integer
);
CREATE RULE "_RETURN" AS ON SELECT TO child_view DO INSTEAD
SELECT child.id, p_data, c_data
FROM parent JOIN child ON (parent_id=parent.id);

问题删除规则

CREATE RULE child_delete AS ON DELETE TO child_view DO INSTEAD(
DELETE FROM child WHERE id=OLD.id;
DELETE FROM parent WHERE p_data=OLD.p_data;
);

上述规则的目的是从组件表中删除 View 中引用的元组。 WHERE p_data=OLD.p_data 对我来说似乎很奇怪,但我看不出还有什么方法可以在父表中引用所需的元组。

以下是我尝试使用上述规则时发生的情况:

>SELECT * FROM child_view;
id | p_data | c_data
----+--------+--------
1 | 1 | 10
2 | 2 | 11
3 | 3 | 12
(3 rows)

>DELETE FROM child_view WHERE id=3;
DELETE 0

>SELECT * FROM child_view;
id | p_data | c_data
----+--------+--------
1 | 1 | 10
2 | 2 | 11
(2 rows)

但是查看父表,删除的第二部分不起作用(id=3“应该”已被删除):

>SELECT * FROM parent;
id | p_data
----+--------
1 | 1
2 | 2
3 | 3
(3 rows)

我应该如何编写删除规则来删除子元组和父元组?

这是使用 postgres v9。

感谢任何帮助。也将不胜感激任何涵盖 postgres 文档之外的 View 规则的 Material (除非我明显遗漏了什么)。谢谢。

编辑:正如 jmz 指出的那样,使用级联删除比使用规则更容易,但这种方法不适用于我的实际模式。

最佳答案

您在规则问题中看到的是规则系统不会以原子方式处理数据。无论 DO INSTEAD 规则中两个语句的顺序如何,都会执行第一个删除。第二条语句永远不会执行,因为 OLD.id 引用的行已从 View 中删除。您可以使用 LEFT JOIN,但这对您没有帮助,因为示例表设计(它可能适用于您的实际数据库架构)。

在我看来,根本问题在于您将规则系统视为触发器。

最好的选择是使用外键和 ON DELETE CASCADE 而不是规则。有了它们,您的示例架构也可以工作:您只需要删除父表即可删除所有子表。

关于postgresql - 如何在 View 上编写删除规则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5534927/

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