Maison > base de données > tutoriel mysql > Comment supprimer une ligne parent dans PostgreSQL si aucun autre enfant n'y fait référence ?

Comment supprimer une ligne parent dans PostgreSQL si aucun autre enfant n'y fait référence ?

Linda Hamilton
Libérer: 2024-10-28 22:31:30
original
626 Les gens l'ont consulté

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

Comment supprimer une ligne parent si aucun autre enfant n'y fait référence

Lors de la suppression d'une ligne enfant dans une table de base de données, cela peut être nécessaire pour supprimer également la ligne parent si aucun autre enfant n'y fait référence. Cela garantit que la base de données maintient l'intégrité référentielle et évite les pointeurs suspendus.

Utilisation d'un CTE de modification des données

PostgreSQL 9.1 et versions ultérieures offrent une solution pratique utilisant un CTE de modification des données expression de table commune (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>
Copier après la connexion

Principales caractéristiques :

  • L'enfant est supprimé sans condition.
  • Le parent est supprimé uniquement s'il ne reste plus de lignes enfants.
  • La dernière condition est cruciale pour éviter les conditions de concurrence et garantir des résultats corrects dans les opérations simultanées.

Élimination des conditions de concurrence

Pour éliminer complètement les conditions de concurrence, verrouillez la ligne parent avant de la supprimer :

<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>
Copier après la connexion

Cette approche garantit qu'une seule transaction peut cibler le même parent à la fois, évitant ainsi des résultats inattendus.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal