【问题标题】:Cascading Delete Without Foreign Key Constraint Postgresql没有外键约束的级联删除 Postgresql
【发布时间】:2019-04-26 00:43:10
【问题描述】:

我想在两个表之间设置级联删除而不强制引用完整性。

例如,假设我有以下两个表:

帖子
+----+---------+
| id | user_id |
+----+---------+
|  1 |       1 |
|  2 |       2 |
|  3 |       3 |
+----+---------+
用户
+----+
| id |
+----+
|  1 |
|  4 |
+----+

我想创建一个约束/触发器,当我在不强制引用完整性的情况下删除帖子中的一行时,删除用户中的引用行。

【问题讨论】:

  • 问题是当级联删除可以为您完成时,为什么要创建类似的东西
  • 数据库中已经有数据,数据不尊重参照完整性。
  • 没有 FK 声明的“引用”是什么意思? “约束/触发器”在这里是什么意思,因为非 FK 约束不会“导致用户中的引用行被删除”?使用足够多的单词句子和对部分示例的引用来清楚。请阅读minimal reproducible example 并采取行动。请通过帖子编辑进行澄清,而不是 cmets。
  • 这是一个常见问题解答。请始终在谷歌上搜索您的问题/问题/目标的许多清晰、简洁和特定的版本/措辞,带和不带您的特定字符串/名称,并阅读许多答案。将您发现的相关关键字添加到搜索中。如果您没有找到答案,请发布,使用 1 个变体搜索作为标签的标题和关键字。请参阅向下投票箭头鼠标悬停文本。如果您确实有要发布的非重复代码问题,请阅读并通过minimal reproducible example 采取行动。
  • 我调整了示例表数据以可视化“数据库中已经有数据并且数据不尊重参照完整性”。

标签: sql postgresql foreign-keys cascading-deletes


【解决方案1】:

你需要一个触发器:

create function delete_users()
  returns trigger
as '
begin
   delete from users where id = old.user_id;
   return null;
end;
' language plpgsql;

create trigger trg_delete_users
  after delete on posts
  for each row execute procedure delete_users();

在线示例:https://rextester.com/MJFCW22289

如果您使用的是 Postgres 10 或更高版本,则语句级触发器可能会更快:

create function delete_users()
  returns trigger
as $trg$
begin
   delete from users where id = (select user_id from old_table);
   return null;
end;
$trg$
language plpgsql;

create trigger trg_delete_users
  after delete on posts
  referencing old table as old_table
  for each statement 
  execute procedure delete_users();

【讨论】:

  • 我认为应该是另一种方式,如果有人采取“当我删除帖子中的一行时导致用户中引用的行被删除”。您希望 FK 和级联位于 users 表中。
猜你喜欢
  • 2011-02-24
  • 2014-01-17
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
相关资源
最近更新 更多