Wstawiłem rekordy do tabeli bazy danych SQL Server. W tabeli zdefiniowano klucz podstawowy, a ziarno tożsamości automatycznego przyrostu jest ustawione na „Tak”. Odbywa się to przede wszystkim dlatego, że w SQL Azure każda tabela musi mieć zdefiniowany klucz podstawowy i tożsamość.
Ale ponieważ muszę usunąć niektóre rekordy z tabeli, ziarno tożsamości dla tych tabel zostanie zakłócone, a kolumna indeksu (która jest generowana automatycznie z przyrostem 1) zostanie zakłócona.
Jak mogę zresetować kolumnę tożsamości po usunięciu rekordów, aby kolumna miała sekwencję w kolejności rosnącej?
Kolumna tożsamości nie jest używana jako klucz obcy w dowolnym miejscu w bazie danych.
Odpowiedzi:
Polecenie
DBCC CHECKIDENT
zarządzania służy do resetowania licznika tożsamości. Składnia polecenia jest następująca:Przykład:
Nie był obsługiwany w poprzednich wersjach bazy danych SQL Azure, ale jest teraz obsługiwany.
Należy pamiętać, że
new_reseed_value
argument jest różny w różnych wersjach SQL Server zgodnie z dokumentacją :Jednak uważam tę informację za mylącą (właściwie po prostu błędną), ponieważ zaobserwowane zachowanie wskazuje, że przynajmniej SQL Server 2012 nadal używa nowej_reseed_value + bieżącej logiki wartości przyrostowej. Microsoft zaprzecza nawet własnej
Example C
znalezionej na tej samej stronie:Mimo to wszystko pozostawia opcję odmiennego zachowania w nowszych wersjach SQL Server. Myślę, że jedynym sposobem, aby się upewnić, dopóki Microsoft nie wyjaśni rzeczy we własnej dokumentacji, jest wykonanie rzeczywistych testów przed użyciem.
źródło
DBCC CHECKIDENT
to, że jest obsługiwany od najbliższego wydania (V12 / Sterling): azure.microsoft.com/en-us/documentation/articles/… Chociaż w tej konkretnej sytuacji nadal polecam TRUNCATE TABLE :)Gdzie 0 to
identity
wartość początkowaźródło
TRUNCATE
, to nowa wartość początkowa powinna być wartością do następnego użycia (tj. 1 nie 0). Jeśli tabela nie jest pusta, użyjenew_reseed_value + 1
. MSDNDELETE
, nieTRUNCATE
, w którym to przypadku równieżnew_reseed+value + 1
. Napisałem o tym post, pokazując rzeczywiste zachowanie za pomocą niektórych testów, i zaktualizowałem aktualny dokument (teraz, gdy możemy to zrobić dzięki GitHubowi ): Jak naprawdę działa DBCC CHECKIDENT podczas resetowania materiału siewnego tożsamości (RESEED)? .Należy zauważyć, że JEŻELI wszystkie dane są usuwane z tabeli za pomocą
DELETE
(tj. BrakWHERE
klauzuli), to tak długo, jak pozwalają na to uprawnienia, i b) nie ma żadnych FK odnoszących się do tabeli (która wydaje się być przypadek tutaj), użycieTRUNCATE TABLE
byłoby preferowane, ponieważ działa bardziej wydajnieDELETE
i resetujeIDENTITY
ziarno w tym samym czasie. Poniższe szczegóły pochodzą ze strony MSDN dla TABELI OBCIĄŻENIA :Więc następujące:
Staje się po prostu:
TRUNCATE TABLE
Dodatkowe informacje na temat ograniczeń itp. Znajdują się w dokumentacji (link powyżej).źródło
Chociaż większość odpowiedzi sugeruje RESEED na 0, ale wiele razy musimy ponownie przejść do następnego dostępnego Id
Spowoduje to sprawdzenie tabeli i zresetowanie do następnego ID.
źródło
declare @max int select @max=ISNULL(max([Id]),0) from [TestTable]; DBCC CHECKIDENT ('[TestTable]', RESEED, @max );
Próbowałem
@anil shahs
odpowiedzieć, a to zresetowało tożsamość. Ale kiedy wstawiono nowy wiersz, dostałidentity = 2
. Zamiast tego zmieniłem składnię na:Wtedy pierwszy wiersz otrzyma tożsamość = 1.
źródło
Mimo, że większość odpowiedzi sugeruje
RESEED
się0
, a gdy niektórzy widzą to jako wada dlaTRUNCATED
tabel, Microsoft ma rozwiązanie, która wykluczaID
Spowoduje to sprawdzenie tabeli i zresetowanie do następnej
ID
. Jest to dostępne od MS SQL 2005 do chwili obecnej.https://msdn.microsoft.com/en-us/library/ms176057.aspx
źródło
Checking identity information: current identity value '[incorrect seed]', current column value '[correct seed]'.
ale przy nowych wstawkach nadal używa niepoprawnego ziarna.wydanie 2 polecenia może załatwić sprawę
pierwszy resetuje tożsamość do zera, a następny ustawi następną dostępną wartość - jacob
źródło
@Jakub
Pracowałem dla mnie, po prostu musiałem najpierw usunąć wszystkie wpisy z tabeli, a następnie dodać powyższe w punkcie aktywacji po usunięciu. Teraz za każdym razem, gdy usuwam, wpis jest pobierany stamtąd.
źródło
Truncate
tabela jest preferowana, ponieważ czyści rekordy, resetuje licznik i odzyskuje miejsce na dysku.Delete
iCheckIdent
powinny być używane tylko wtedy, gdy klucze obce uniemożliwiają obcięcie.źródło
Zresetuj kolumnę tożsamości z nowym identyfikatorem ...
źródło
To jest częste pytanie i odpowiedź jest zawsze taka sama: nie rób tego. Wartości tożsamości należy traktować jako arbitralne i jako takie nie ma „prawidłowej” kolejności.
źródło
Uruchom ten skrypt, aby zresetować kolumnę tożsamości. Musisz wprowadzić dwie zmiany. Zastąp tableXYZ dowolnym stołem, który chcesz zaktualizować. Ponadto nazwa kolumny tożsamości musi zostać usunięta z tabeli tymczasowej. Było to natychmiastowe na stole z 35 000 wierszy i 3 kolumnami. Oczywiście wykonaj kopię zapasową tabeli i najpierw wypróbuj ją w środowisku testowym.
źródło
Spowoduje to ustawienie bieżącej wartości tożsamości na 0.
Po wstawieniu następnej wartości wartość tożsamości zwiększa się do 1.
źródło
Użyj tej procedury składowanej:
Powracam do mojej odpowiedzi. Natknąłem się na dziwne zachowanie na serwerze SQL Server 2008 R2, o którym powinieneś wiedzieć.
Pierwszy wybór produkuje
0, Item 1
.Drugi produkuje
1, Item 1
. Jeśli wykonasz reset zaraz po utworzeniu tabeli, następna wartość to 0. Szczerze mówiąc, nie jestem zaskoczony, że Microsoft nie może tego poprawnie zrobić. Odkryłem go, ponieważ mam plik skryptu, który zapełnia tabele referencyjne, które czasem uruchamiam po ponownym utworzeniu tabel, a czasem po ich utworzeniu.źródło
Aby to zrobić, używam następującego skryptu. Jest tylko jeden scenariusz, w którym spowoduje „błąd”, czyli usunięcie wszystkich wierszy z tabeli, a
IDENT_CURRENT
obecnie jest ustawiony na 1, tzn. Na początku był tylko jeden wiersz w tabeli.źródło
Do pełnego usunięcia wierszy i zresetowania liczby TOŻSAMOŚCI używam tego (SQL Server 2008 R2)
źródło
Resesekcja do zera nie jest zbyt praktyczna, chyba że czyścisz stół jako całość.
w przeciwnym razie odpowiedź udzielona przez Anthony'ego Raymonda jest idealna. Zdobądź najpierw kolumnę maks. Tożsamości, a następnie zapisz ją maks.
źródło
Podczas programowania starałem się to zrobić dla dużej liczby tabel, a to działa jak urok.
Najpierw wymuszasz ustawienie go na 1, a następnie ustawiasz go na najwyższy indeks wierszy obecnych w tabeli. Szybka i łatwa reszta ideksu.
źródło
Zawsze lepiej jest użyć TRUNCATE gdy jest to możliwe, zamiast usuwać wszystkie rekordy, ponieważ nie wykorzystuje również miejsca w dzienniku.
W przypadku, gdy potrzebujemy usunąć i zresetować ziarno, zawsze pamiętaj, że jeśli tabela nigdy nie została zapełniona i użyłeś,
DBCC CHECKIDENT('tablenem',RESEED,0)
to pierwszy rekord uzyska tożsamość = 0, jak podano w dokumentacji msdnźródło
TRUNCATE
to uniemożliwiłobyROLLBACK
zachowanie się zgodnie z oczekiwaniami? ROLLBACK wciąż się wycofuje. Nawet jeśli DB jest ustawiony naBULK_LOGGED
.Po pierwsze: specyfikacja tożsamości Tylko: „Nie” >> Zapisz bazę danych Wykonaj projekt
Następnie: Specyfikacja tożsamości Tylko: „TAK” >> Zapisz bazę danych Wykonaj projekt
Twój identyfikator bazy danych, PK Zacznij od 1 >>
źródło