他の子が参照していない場合に 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 を使用した便利なソリューションが提供されています。共通テーブル式 (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>
ログイン後にコピー

このアプローチにより、一度に 1 つのトランザクションのみが同じ親をターゲットにできるようになり、予期しない結果が防止されます。

以上が他の子が参照していない場合に PostgreSQL の親行を削除するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!