如何在 PostgreSQL 中實現子級刪除時級聯父級刪除?

Patricia Arquette
發布: 2024-11-01 00:28:29
原創
530 人瀏覽過

How to Implement Cascading Parent Deletion Upon Child Removal in PostgreSQL?

子級刪除時級聯父級刪除

在父表有引用子行的列的情況下,有必要刪除父級記錄是否沒有剩餘子行。 PostgreSQL 提供了多種方法來實現此目的。

一種方法是透過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   -- (1)
   );</code>
登入後複製

透過此CTE,子層級總是被刪除,而子層級總是被刪除,而子層級總是被刪除,而子層級總是被刪除,而父級只有在沒有其他子級時才會被刪除。請注意,條件 (1) 對於避免並發操作產生意外結果至關重要。

但是,這種方法不能避免競爭條件。要完全消除它們,可以在刪除之前鎖定父行:

<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              -- (2)
   FOR    NO KEY UPDATE                -- (3)
   )
 , 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   -- (4)
   );</code>
登入後複製

在這種情況下,只有一個交易可以鎖定同一父行,從而防止並發刪除的情況。 (2) 是要刪除的子行。雖然 (3) 鎖定父行,但 (4) 在刪除父行之前驗證不存在其他子行。

為了清楚起見,條件 (1) 和 (4) 透過確保父行是防止「錯誤」刪除的僅當沒有剩餘子項時才刪除。

以上是如何在 PostgreSQL 中實現子級刪除時級聯父級刪除?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!