Estamos en un caso muy común, por ejemplo, una tabla intermedia sin primary key en la que hemos hecho un bulk de un fichero con datos y queremos pasar estos datos a una tabla final que si tiene primary key.
Para garantizar que no se produce un error por violación de la PK tenemos que limpiar los registros duplicados en la tabla inical.
Podemos hacerlo de varias formas, esta es una posibilidad entre muchas pero que a mi me gusta mucho utilizar. Consiste en utilizar una Common Table Expression, CTE, con la clausula OVER.
En la tabla inicial, tablaEjemplo, tenemos que eliminar los duplicados por los campos que forman la PK de la tabla final, campo1 y campo2, y en caso de que haya repetidos, el criterio de selección será el que establezcamos en la clausula ORDER, en este ejemplo campo3 descendente y campos 4 ascendente. Como se eliminan los registros con ROW1>1 nos estamos quedando con el primer registro que cumpla dicho criterio de ordenación dentro de cada grupo de registros con mismo campo1 y campo2:
with CTE as (
select T.*,
row_number() OVER (PARTITION BY T.campo1, T.campo2
ORDER BY T.campo3 desc, T.campo4 asc) as ROW1
FROM tablaEjemplo T
)
delete from CTE where ROW1>1;
En este caso los registros se eliminan sin dejar rastro, pero podemos crear una tabla a la que redirigir estos registros para que podamos revisarlos si es necesario.
Creamos una tabla de nombre tablaEjemploDup con los mismos campos que la inicial pero un campo adicional al principio de tipo fecha y hacemos el borrado con esta sentencia:
with CTE as (
select T.*,
row_number() OVER (PARTITION BY T.campo1, T.campo2
ORDER BY T.campo3 desc, T.campo4 asc) as ROW1
FROM tablaEjemplo T
)
delete from CTE
OUTPUT getdate(), Deleted.* into tablaEjemploDup
where ROW1>1;
La clausua OUTPUT nos redirige los registros eliminados a la nueva tabla, tablaEjemploDup.
Por ultimo, seria interesante controlar el numero de registros eliminados y en caso de que sean mayor que cero configurar algún tipo de alerta para que los datos sean revisados:
set @numRows = @@ROWCOUNT
if @numrows>0 exec sp_ProcedimientoAlertas ...
Con esto hemos terminado, espero que le sea de utilidad a alguien.
Un saludo
No hay comentarios:
Publicar un comentario