2010-04-07 15 views
26

Mam dwukolumnowy klucz podstawowy na stole. Starałem się zmienić to ustawienie ignore_dup_key do na z tym poleceniem:Czy mogę ustawić ignore_dup_key na klucz podstawowy?

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

Ale otrzymuję ten błąd:

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

Jak inaczej mam ustawiony IGNORE_DUP_KEY się na?

Odpowiedz

21

Nie jest to udokumentowane w Books Online, ale odkryłem, że chociaż jest to poprawne dla kluczy podstawowych, nie można tego zmienić za pomocą INDEKTU ZMIENNEGO, trzeba będzie upuścić i ponownie utworzyć klucz podstawowy.

Należy pamiętać, że ta flaga nie pozwalają właściwie przechowywać zduplikowane wiersze, to po prostu błąd, który zmienia wyniki:

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. 

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

3

Określa, co się dzieje po włożeniu duplikaty tylko

Zobacz 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.

..i to nie ma zastosowania do PK

Komentarz BOL dla ALTER TABLE na ten temat i "kompatybilność wsteczna" jest nieco myląca. Właśnie próbowałem tego i BradC jest poprawny.

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

Zauważ, że to ustawienie dotyczy tylko tego, co dzieje się w przypadku próby wstawienia duplikat klucza, to nie będzie można wstawić duplikat klucza.

Jeśli próbujesz wstawić zduplikowane klucze, możesz usunąć indeks klucza głównego, wstawić rekordy, naprawić dane (usunąć duplikaty itd.), A następnie utworzyć ponownie indeks.

0

Osobiście nie chcę go zignorować duplikować. Jeśli istnieje duplikat klucza podstawowego, musi on zostać naprawiony. Nie chcę, aby był ignorowany, a inne wpisy wstawiane, ponieważ wtedy użytkownik mógłby pomyśleć, że wszystkie zostały wstawione. To ustawienie jest maską dla nieprawidłowego procesu wstawiania. Dobrze zaprojektowany proces nie potrzebuje tego ustawienia, ponieważ czyści dane przed ich wprowadzeniem (lub używa aktualizacji do aktualizacji istniejących i wstawia nowe) i wysyła błędne rekordy do tabeli, aby można je było naprawić i ponownie wstawić lub wysłać błąd z powrotem do użytkownika, aby wiedzieli, że ich zapis nie został wstawiony.

+2

Mój problem jest taki: muszę wstawić dużą liczbę rekordów codziennie i jestem obecnie robi polecenie insert dla każdego rekordu. Jeśli rekord już istnieje, zostanie zignorowany (poprzez zgłoszenie duplikatu błędu klucza). Z POV wydajności lepiej jest spróbować wstawić i pozwolić niektórym zawodzić, niż sprawdzić, czy rekord istnieje przed wstawieniem. Następnym krokiem do poprawy wydajności jest użycie SqlBulkCopy do wykonania wstawek zamiast pojedynczego polecenia dla każdego rekordu. Ale nie jest to możliwe, jeśli istnieje jakikolwiek rekord, ponieważ cała partia zakończy się niepowodzeniem, jeśli ignore_dup_key jest wyłączony. –

+0

Co zrobić, jeśli jedna z kolumn mojego klucza podstawowego jest zdefiniowana przez użytkownika? A co, jeśli muszę obsługiwać wstawienia wielu jednostek jednocześnie, powiedzmy 1000? Jak mogę sprawdzić, czy wszystkie wpisy są unikatowe przed wstawieniem bez dużego obciążenia serwera?Myślę, że opcja ignorowania duplikatu jest w tej sytuacji odpowiednia. Czy się nie zgadzasz? – julealgon

+0

Tak, nie kluczujesz, jeśli zignorujesz duplikaty, a jeśli nie, klucz podstawowy, to ostatecznie będziesz miał świat pełen urazów ze złymi danymi. Lepszą praktyką jest umieszczanie danych w tabeli pomostowej, a następnie użycie instrukcji select do wstawiania tylko nowych rekordów. W ten sposób wstawiamy milion rekordów. – HLGEM

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

Nie działa z Postgresql - 9.5 PSQL nie rozumie słowa kluczowego IGNORE_DUP_KEY. Czy istnieje sposób, aby to zrobić (lub coś podobnego) działa w Postgresql> = 9.5 – Bhindi

+0

Nie wiem. To pytanie zostało oznaczone jako serwer-sql, więc spróbuj wyszukać podobne pytania dla PostgreSQL. – Kvasi

Powiązane problemy