加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – 如何在视图上编写删除规则?

发布时间:2020-12-13 16:01:03 所属栏目:百科 来源:网络整理
导读:我正在尝试在视图上编写规则以从组件表中删除元组,但到目前为止只能从其中一个中删除数据.我已经使用了一段时间基本视图的postgres,但我对视图规则没有任何经验. 我写了一个愚蠢的小测试用例来弄清楚/显示我的问题.在这个例子中,每个子元组只有一个父元组(我
我正在尝试在视图上编写规则以从组件表中删除元组,但到目前为止只能从其中一个中删除数据.我已经使用了一段时间基本视图的postgres,但我对视图规则没有任何经验.

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

组件表:

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;
);

上述规则的目的是从组件表中删除视图中引用的元组. 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“should”已被删除):

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

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

这是使用postgres v9.

任何帮助表示赞赏.除了postgres文档之外,还有指向任何涵盖视图规则的材料的指示(除非我明显错过了某些内容)也将受到赞赏.谢谢.

编辑:正如jmz所指出的,在这里使用级联删除比使用规则更容易,但是这种方法对我的实际模式不起作用.

解决方法

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

正如我所看到的,根本问题在于你正在对规则系统进行处理,因为它是一个触发器.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读