2010-04-07 14 views
26

Ho una chiave primaria a due colonne su un tavolo. Ho cercato di modificarlo per impostare il ignore_dup_key su on con questo comando:Posso impostare ignore_dup_key su per una chiave primaria?

ALTER INDEX PK_mypk on MyTable 
SET (IGNORE_DUP_KEY = ON); 

ma ottengo questo errore:

Cannot use index option ignore_dup_key to alter index 'PK_mypk' as it enforces a primary or unique constraint.

Altrimenti come devo impostare IGNORE_DUP_KEY su on?

risposta

21

Non è documentato in Libri in linea, ma ho trovato che mentre questo è valido per chiavi primarie, non è possibile modificare questo con un INDICE ALTER, sarà necessario rilasciare e ricreare la chiave primaria.

Tenete a mente che questo flag non consente di memorizzare in realtà le righe duplicate, cambia semplicemente l'errore che i risultati:

ON 
A warning message will occur when duplicate key values are inserted into a unique 
index. Only the rows violating the uniqueness constraint will fail. 

OFF 
An error message will occur when duplicate key values are inserted into a 
unique index. The entire INSERT operation will be rolled back. 

Da http://msdn.microsoft.com/en-us/library/ms175132.aspx

3

Si determina cosa accade quando si inserisce duplicati solo

Vedi ALTER TABLE..index option

Specifies the error response when an insert operation attempts to insert duplicate key values into a unique index. The IGNORE_DUP_KEY option applies only to insert operations after the index is created or rebuilt. The option has no effect when executing CREATE INDEX, ALTER INDEX, or UPDATE.

..e non si applica a PKs

Il commento BOL per ALTER TABLE su questo e la "retrocompatibilità" è alquanto confusa. L'ho appena provato e BradC è corretto.

CREATE TABLE dbo.foo (bar int PRIMARY KEY WITH (FILLFACTOR=90, IGNORE_DUP_KEY = ON)) 
GO 
INSERT dbo.foo VALUES (1) 
GO 
INSERT dbo.foo VALUES (1) 
GO 
--gives  
(1 row(s) affected) 

Duplicate key was ignored. 

(0 row(s) affected) 
0

Si noti che questa impostazione ha effetto solo cosa succede se si tenta di inserire una chiave duplicata, non permetterà di inserire una chiave duplicata.

Se si sta tentando di inserire chiavi duplicate, è possibile rilasciare l'indice della chiave primaria, inserire i record, correggere i dati (rimuovere i duplicati, ecc.), Quindi ricreare l'indice.

0

Personalmente non ho mai vogliono ignorare il duplicare. Se esiste un valore duplicato per una chiave primaria, deve essere corretto. Non voglio che venga ignorato e gli altri record inseriti perché l'utente potrebbe pensare che tutti siano stati inseriti. Questa impostazione è un cover-up per un processo di inserimento errato. Un processo ben progettato non ha bisogno di questa impostazione poiché pulisce i dati prima di immetterli (o usa upsert per aggiornare esistenti e inserirne di nuovi) e invia i record non validi a una tabella in modo che possano essere riparati e reinseriti o invia un errore di nuovo all'utente, in modo che sappiano che il loro record non è stato inserito.

+2

Il mio problema è questo: ho bisogno di inserire un gran numero di record ogni giorno e sto facendo un comando di inserimento per ogni record. Se il record esiste già, viene ignorato (generando un errore chiave duplicato). Da un POV delle prestazioni è meglio tentare un inserto e consentire ad alcuni di fallire piuttosto che controllare se il record esiste prima di inserirlo. Il passaggio successivo per migliorare le prestazioni consiste nell'utilizzare SqlBulkCopy per eseguire gli inserimenti anziché un singolo comando per ogni record. Ma questo non è possibile se esiste un record in quanto l'intero batch fallisce se ignore_dup_key è disattivato. –

+0

Cosa succede se una delle colonne sulla mia chiave primaria è definita dall'utente? E se avessi bisogno di supportare inserimenti di più entità contemporaneamente, diciamo 1000? Come potrei verificare che tutte le voci siano univoche prima dell'inserimento senza un grave impatto sul server?Penso che l'opzione ignora duplicata sia abbastanza appropriata in quella situazione. Sei in disaccordo? – julealgon

+0

Sì, non hai la chiave principale se ignori i duplicati e se non usi una chiave primaria, allora alla fine avrai un mondo di male con i dati cattivi. È una pratica migliore inserire i dati in una tabella di staging e quindi utilizzare un'istruzione select per inserire solo i nuovi record. Inseriamo milioni di record in questo modo. – HLGEM

48
ALTER TABLE [TableName] REBUILD WITH (IGNORE_DUP_KEY = ON) 
+0

Non funziona con Postgresql - 9.5 PSQL non capisce la parola chiave IGNORE_DUP_KEY. C'è un modo per farlo funzionare (o qualcosa di simile) in Postgresql> = 9.5 – Bhindi

+0

Non so. Questa domanda è contrassegnata da sql-server, quindi prova a cercare domande simili per PostgreSQL. – Kvasi

Problemi correlati