Puede hacer esto de manera mucho más eficiente con una instrucción SQL única con CTE de modificación de datos .
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 aquí
(pág. 11)
SQL Fiddle
(pág. 9.6)
Esto debería ser mucho más rápido y más limpio. Los bucles son comparativamente caros, el manejo de excepciones es comparativamente aún más caro.
Más importante aún, las referencias en lab
se redirigen a la fila principal respectiva en cpt
automáticamente, que aún no estaba en su código original. Para que pueda eliminar todos los duplicados a la vez .
Todavía puede envolver esto en una función plpgsql o SQL si lo desea.
Explicación
-
En el 1er CTE
plan
, identifique una fila maestra en cada partición con el mismocdesc
. En su caso, la fila con el mínimorecid
. -
En el 2º CTE
upd_lab
redirigir todas las filas que hacen referencia a un duplicado a la fila principal encpt
. -
Finalmente, elimine duplicados, lo que no generará excepciones porque las filas dependientes se vinculan a la fila maestra restante prácticamente al mismo tiempo.
ON DELETE RESTRICT
Todas las CTE y la consulta principal de una sentencia operar en la misma instantánea de tablas subyacentes, virtualmente simultáneamente . No ven los efectos de los demás en las tablas subyacentes:
Uno podría esperar una restricción FK con ON DELETE RESTRICT
generar excepciones porque, [según la documentación][3]:
Sin embargo, la declaración anterior es un comando único y, [el manual otra vez][3]:
Énfasis en negrita mío. Funciona para el valor predeterminado menos restrictivo ON DELETE NO ACTION
también, por supuesto.
Pero tenga cuidado con las transacciones simultáneas que se escriben en las mismas tablas, pero esa es una consideración general, no específica de esta tarea.
Se aplica una excepción para UNIQUE
y PRIMARY KEY
restricción, pero eso no concierne a esto caso: