Heim >Datenbank >MySQL-Tutorial >Wie lösche ich eine übergeordnete Zeile in PostgreSQL, wenn keine anderen untergeordneten Zeilen darauf verweisen?

Wie lösche ich eine übergeordnete Zeile in PostgreSQL, wenn keine anderen untergeordneten Zeilen darauf verweisen?

Linda Hamilton
Linda HamiltonOriginal
2024-10-28 22:31:30632Durchsuche

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

So löschen Sie eine übergeordnete Zeile, wenn keine anderen untergeordneten Zeilen darauf verweisen

Beim Löschen einer untergeordneten Zeile in einer Datenbanktabelle kann es erforderlich sein um auch die übergeordnete Zeile zu löschen, wenn keine anderen untergeordneten Elemente darauf verweisen. Dadurch wird sichergestellt, dass die Datenbank die referenzielle Integrität beibehält und baumelnde Zeiger verhindert werden.

Verwendung eines CTE zur Datenänderung

PostgreSQL 9.1 und höher bieten eine praktische Lösung mithilfe einer Datenänderung allgemeiner Tabellenausdruck (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>

Hauptmerkmale:

  • Das untergeordnete Element wird bedingungslos gelöscht.
  • Das übergeordnete Element wird gelöscht Nur wenn keine verbleibenden untergeordneten Zeilen mehr vorhanden sind.
  • Die letzte Bedingung ist entscheidend, um Rennbedingungen zu verhindern und korrekte Ergebnisse bei gleichzeitigen Vorgängen sicherzustellen.

Beseitigen von Rennbedingungen

Um Race Conditions vollständig zu beseitigen, sperren Sie die übergeordnete Zeile vor dem Löschen:

<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>

Dieser Ansatz stellt sicher, dass jeweils nur eine Transaktion auf dasselbe übergeordnete Element abzielen kann, wodurch unerwartete Ergebnisse verhindert werden.

Das obige ist der detaillierte Inhalt vonWie lösche ich eine übergeordnete Zeile in PostgreSQL, wenn keine anderen untergeordneten Zeilen darauf verweisen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn