Dopo un'importazione o a causa di un errore di inserimento è possibile imbattersi in un problema particolare quello dei record duplicati all'interno di una tabella. Con l'Enterprise Manager quando li si vuole cancellare viene restituito un errore (Informazioni sulla colonna chiave insufficienti o errate. Troppe righe interessate dall'aggiornamento o in inglese Key column information is insufficient or incorrect. Too many were affected by update), ovvero il DBMS non è in gradi di individuare quale record deve cancellare perchè tutti i campi hanno lo stesso valore e quindi nessuna clausola where potrebbe permettere la rimozioni di uno dei due.
Ci sono molti modi per cancellare i record doppi.
Per prima cosa dobbiamo creare un esempio, quindi creare una tabella ed inserire dei record
-- Creazione della tabella di esempio create table tabella1 ( campo1 integer, campo2 varchar(20), campo3 datetime ) -- Creazione dei dati di esempio insert into tabella1 values (1,'pippo','2005-01-01') insert into tabella1 values (1,'pluto','2005-01-01') insert into tabella1 values (2,'paperino','2005-12-31')
A questo punto si crea il record doppio
-- Creazione del duplicato insert into tabella1 values (1,'pluto','2005-01-01')
L'idea di base è quella di creare una tabella temporanea dove si vanno a scrivere in modo univoco tutti i record doppi, facendo una distinct o una group by su tutti i campi.
-- Creazione della tabella temporanea create table #duplicati_tabella1 ( campo1 integer, campo2 varchar(20), campo3 datetime ) -- Identificazione dei record doppi insert into #duplicati_tabella1 select * from tabella1 group by campo1, campo2, campo3 having count(*) > 1
Una volta messi da parte i record doppi si possono cancellare dalla tabella principale.
-- cancellazione dei record doppi dalla tabella principale delete from tabella1 from tabella1 join #duplicati_tabella1 on tabella1.campo1 = #duplicati_tabella1.campo1 and tabella1.campo2 = #duplicati_tabella1.campo2 and tabella1.campo3 = #duplicati_tabella1.campo3
Solo adesso si possono reinserire i record che prima erano doppi.
-- inserimento dei record singoli insert into tabella1 select * from #duplicati_tabella1
Giusto un controllo finale e la cancellazione della tabella temporanea.
-- confrollo finale select * from tabella1 group by campo1, campo2, campo3 having count(*) > 1 -- cancellazione della tabella dei duplicati drop table #duplicati_tabella1
Questo secondo metodo non è molto bello, sconsigliabile se la tabella è delicata. Però è molto veloce se di fatto è un solo record da cancellare o non si ha il tempo di scrivere lunghe query (l'esempio precedente era formato da una tabella di soli tre campi).
L'idea è quella di creare un nuova campo nella tabella come int Identity (identificatore univoco). Alla creazione del campo SQL Server popola questo campo andando a scandire fisicamente la tabella quindi non facendo alcun controllo logico sul valore dei dati. Adesso le righe non sono più tutte uguali ed è possibile cancellare i duplicati. Alla fine basta rimuovere di nuovo la colonna identity.