如果没有其他子项引用它,如何删除 PostgreSQL 中的父行?

Linda Hamilton
发布: 2024-10-28 22:31:30
原创
548 人浏览过

How to Delete a Parent Row in PostgreSQL if No Other Children Reference It?

如果没有其他子级引用父行,如何删除它

删除数据库表中的子行时,可能有必要如果没有其他子项引用它,也可以删除父行。这可以确保数据库保持引用完整性并防止悬空指针。

使用数据修改 CTE

PostgreSQL 9.1 及更高版本提供了使用数据修改的便捷解决方案公用表表达式 (CTE):

<code class="sql">WITH del_child AS (
    DELETE FROM child
    WHERE  child_id = 1
    RETURNING parent_id, child_id
    )
DELETE FROM parent p
USING  del_child x
WHERE  p.parent_id = x.parent_id
AND    NOT EXISTS (
   SELECT FROM child c
   WHERE  c.parent_id = x.parent_id
   AND    c.child_id <> x.child_id   -- !
   );</code>
登录后复制

主要功能:

  • 无条件删除子级。
  • 父级被删除仅当它不再有任何剩余子行时。
  • 最后一个条件对于防止竞争条件并确保并发操作中的正确结果至关重要。

消除竞争条件

要完全消除竞争条件,请在删除之前锁定父行:

<code class="sql">WITH lock_parent AS (
   SELECT p.parent_id, c.child_id
   FROM   child  c
   JOIN   parent p ON p.parent_id = c.parent_id
   WHERE  c.child_id = 12              -- provide child_id here once
   FOR    NO KEY UPDATE                -- locks parent row.
   )
 , del_child AS (
   DELETE FROM child c
   USING  lock_parent l
   WHERE  c.child_id = l.child_id
   )
DELETE FROM parent p
USING  lock_parent l
WHERE  p.parent_id = l.parent_id
AND    NOT EXISTS (
   SELECT FROM child c
   WHERE  c.parent_id = l.parent_id
   AND    c.child_id <> l.child_id   -- !
   );</code>
登录后复制

此方法可确保一次只有一个事务可以针对同一父级,从而防止出现意外结果。

以上是如果没有其他子项引用它,如何删除 PostgreSQL 中的父行?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!