Sie können dies viel effizienter mit einer einzelnen SQL-Anweisung tun mit datenmodifizierende CTEs .
WITH plan AS (
SELECT *
FROM (
SELECT recid, min(recid) OVER (PARTITION BY cdesc) AS master_recid
FROM cpt
) sub
WHERE recid <> master_recid -- ... <> self
)
, upd_lab AS (
UPDATE lab l
SET cpt_recid = p.master_recid -- link to master recid ...
FROM plan p
WHERE l.cpt_recid = p.recid
)
DELETE FROM cpt c
USING plan p
WHERE c.recid = p.recid
RETURNING c.recid;
db<>fiddle hier
(Seite 11)
SQL Fiddle
(Seite 9.6)
Das sollte viel sein schneller und sauberer. Looping ist vergleichsweise teuer, Ausnahmebehandlung ist vergleichsweise noch teurer.
Wichtiger noch, Referenzen im lab
werden in cpt
in die jeweilige Hauptzeile umgeleitet automatisch, was noch nicht in Ihrem ursprünglichen Code enthalten war. Sie können also alle Duplikate auf einmal löschen .
Sie können dies immer noch in eine plpgsql- oder SQL-Funktion packen, wenn Sie möchten.
Erklärung
-
Im 1. CTE
plan
, identifizieren Sie eine Hauptzeile in jeder Partition mit demselbencdesc
. In Ihrem Fall die Zeile mit dem Minimumrecid
. -
Im 2. CTE
upd_lab
leitet alle Zeilen, die auf ein Dupe verweisen, in die Hauptzeile incpt
um . -
Löschen Sie schließlich Dupes, was keine Ausnahmen hervorrufen wird, da abhängige Zeilen praktisch gleichzeitig mit der verbleibenden Master-Zeile verknüpft werden.
ON DELETE RESTRICT
Alle CTEs und die Hauptabfrage einer Anweisung auf demselben Snapshot der zugrunde liegenden Tabellen praktisch gleichzeitig arbeiten . Sie sehen die Auswirkungen der anderen auf die zugrunde liegenden Tabellen nicht:
- Übergeordnetes Element löschen, wenn es von keinem anderen untergeordneten Element referenziert wird
Man könnte eine FK-Einschränkung mit ON DELETE RESTRICT
erwarten Ausnahmen auslösen, weil [per Dokumentation][3]:
Die obige Anweisung ist jedoch ein einzelner Befehl und [nochmals das Handbuch][3]:
Fette Hervorhebung von mir. Funktioniert für die weniger restriktive Standardeinstellung ON DELETE NO ACTION
natürlich auch.
Aber seien Sie vorsichtig bei gleichzeitigen Transaktionen, die in dieselben Tabellen schreiben, aber das ist eine allgemeine Überlegung, nicht spezifisch für diese Aufgabe.
Eine Ausnahme gilt für UNIQUE
und PRIMARY KEY
Beschränkung, aber das betrifft das nicht Fall: