Zresetuj ziarno tożsamości po usunięciu rekordów w SQL Server


682

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.


4
„w SQL Azure” - „każda tabela musi mieć klucz podstawowy” - prawda - ”i tożsamość zdefiniowana” - fałsz. Tożsamość i klucz podstawowy to pojęcia ortogonalne. Kolumna tożsamości nie musi być PK tabeli. Klucz podstawowy nie musi być kolumną tożsamości.
Damien_The_Unbeliever

OK. Moja koncepcja może być błędna. Ale teraz zdefiniowałem strukturę tabeli za pomocą PK i Identity Seed. Jeśli muszę usunąć niektóre wiersze, jak mogę zresetować ziarno tożsamości w poprawnej kolejności numerycznej
xorpower

29
Zawsze twierdziłbym, że jeśli zależy ci na rzeczywistych wartościach liczbowych generowanych w kolumnie tożsamości, niewłaściwie je wykorzystujesz. Wszystko, na co powinieneś zwrócić uwagę, to kolumna tożsamości, która automatycznie generuje unikalne wartości (yay!) I że możesz przechowywać te wartości w kolumnie numerycznej (ten bit jest odpowiedni tylko dla deklarowania, że ​​kolumny przechowują te wartości). Nie powinieneś pokazywać ich nikomu, więc nie powinno mieć znaczenia, jakie wartości przyjmą.
Damien_The_Unbeliever

możesz użyć identyfikatora sprawdzania dbcc jak wspomniano wcześniej, ale pamiętaj, że klucz podstawowy nie jest obowiązkowy dla sql db v12
Satya_MSFT

Odpowiedzi:


1099

Polecenie DBCC CHECKIDENTzarządzania służy do resetowania licznika tożsamości. Składnia polecenia jest następująca:

DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value ]}}])
[ WITH NO_INFOMSGS ]

Przykład:

DBCC CHECKIDENT ('[TestTable]', RESEED, 0);
GO

Nie był obsługiwany w poprzednich wersjach bazy danych SQL Azure, ale jest teraz obsługiwany.


Należy pamiętać, że new_reseed_valueargument jest różny w różnych wersjach SQL Server zgodnie z dokumentacją :

Jeśli wiersze są obecne w tabeli, następny wiersz jest wstawiany z wartością new_reseed_value . W wersji SQL Server 2008 R2 i wcześniejszych, następny wstawiony wiersz używa nowej_reseed_value + bieżąca wartość przyrostu.

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 Cznalezionej na tej samej stronie:

C. Zmuszenie bieżącej wartości tożsamości do nowej wartości

Poniższy przykład wymusza bieżącą wartość tożsamości w kolumnie AddressTypeID w tabeli AddressType na wartość 10. Ponieważ tabela zawiera istniejące wiersze, następny wstawiony wiersz użyje 11 jako wartości, czyli nowej bieżącej wartości przyrostu zdefiniowanej dla wartość kolumny plus 1.

USE AdventureWorks2012;  
GO  
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);  
GO

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.


23
Składnia będzie ... DBCC CHECKIDENT ('[TestTable]', RESEED, 0) GO
Biki

2
Wygląda na DBCC CHECKIDENTto, ż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 :)
Solomon Rutzky

1
Nie działało to dla mnie, dopóki „GO” nie znalazł się w innej linii.
mrówa

1
Składnia jest oznaczana z powodu słowa kluczowego GO w tym samym wierszu, nie wiem dlaczego. Czy możesz to przesunąć w dół o linię. Skopiowałem i wkleiłem ten wiersz 50 razy i teraz muszę wrócić i go naprawić.
AnotherDeveloper

4
Działa idealnie dla mnie. Warto zauważyć, że przy ponownym zasiewie tabeli, jeśli chcesz zresetować, aby twój pierwszy rekord miał identyfikator 1, to polecenie reseed musi zostać zresetowane do 0, tak aby następny rekord był identyfikatorem 1.
Mike Upjohn

215
DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO

Gdzie 0 to identitywartość początkowa


15
Jeśli tabela jest pusta, np. Jeśli dopiero co wywołałeś 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żyje new_reseed_value + 1. MSDN
kjbartel

2
@kjbartel, Anil i inni: to nie jest tak proste jak tylko „jeśli stół jest pusty”. W dokumentacji brakowało przypadku, gdy tabela jest pusta z powodu DELETE, nie TRUNCATE, 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)? .
Solomon Rutzky

87

Należy zauważyć, że JEŻELI wszystkie dane są usuwane z tabeli za pomocą DELETE(tj. Brak WHEREklauzuli), 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życie TRUNCATE TABLEbyłoby preferowane, ponieważ działa bardziej wydajnie DELETE i resetuje IDENTITYziarno w tym samym czasie. Poniższe szczegóły pochodzą ze strony MSDN dla TABELI OBCIĄŻENIA :

W porównaniu do instrukcji DELETE, TRUNCATE TABLE ma następujące zalety:

  • Wykorzystywane jest mniej miejsca w dzienniku transakcji.

    Instrukcja DELETE usuwa wiersze pojedynczo i rejestruje wpis w dzienniku transakcji dla każdego usuniętego wiersza. TRUNCATE TABLE usuwa dane poprzez cofnięcie przydziału stron danych używanych do przechowywania danych tabeli i zapisuje tylko dezalokacje stron w dzienniku transakcji.

  • Zazwyczaj stosuje się mniej blokad.

    Gdy instrukcja DELETE jest wykonywana przy użyciu blokady wierszy, każdy wiersz w tabeli jest blokowany do usunięcia. TRUNCATE TABLE zawsze blokuje tabelę (w tym blokowanie schematu (SCH-M)) i strony, ale nie każdy wiersz.

  • Bez wyjątku w tabeli pozostaje zero stron.

    Po wykonaniu instrukcji DELETE tabela może nadal zawierać puste strony. Na przykład pustych stron w stosie nie można cofnąć bez przynajmniej wyłącznej blokady tabeli (LCK_M_X). Jeśli operacja usuwania nie korzysta z blokady tabeli, tabela (sterta) będzie zawierać wiele pustych stron. W przypadku indeksów operacja usuwania może pozostawić puste strony, chociaż strony te zostaną szybko zwolnione przez proces czyszczenia w tle.

Jeśli tabela zawiera kolumnę tożsamości, licznik dla tej kolumny jest resetowany do wartości początkowej zdefiniowanej dla kolumny. Jeśli nie zdefiniowano nasion, używana jest wartość domyślna 1. Aby zachować licznik tożsamości, użyj zamiast tego DELETE.

Więc następujące:

DELETE FROM [MyTable];
DBCC CHECKIDENT ('[MyTable]', RESEED, 0);

Staje się po prostu:

TRUNCATE TABLE [MyTable];

TRUNCATE TABLEDodatkowe informacje na temat ograniczeń itp. Znajdują się w dokumentacji (link powyżej).


8
Chociaż jest bardziej wydajny w odpowiednich okolicznościach, nie zawsze jest to opcja. Obcinanie nie będzie wykonywane w przypadku tabeli, dla której zdefiniowano FK. Nawet jeśli nie ma żadnych rekordów zależnych, obcinanie zakończy się niepowodzeniem, jeśli ograniczenie istnieje. Również obcinanie wymaga uprawnień ZMIEŃ, w przypadku gdy Usuń wymaga tylko USUŃ.
Rozwel

3
@Rozwel To prawda, ale już zakwalifikowałem swoją odpowiedź, stwierdzając, że należy wprowadzić odpowiednie uprawnienia. Ponadto pytanie wyraźnie stwierdza, że ​​nie ma FK. Jednak dla jasności zaktualizowałem, aby określić ograniczenie „brak FK”. Dzięki za zwrócenie na to uwagi.
Solomon Rutzky

1
tylko spór jest taki, że dowolny FK zablokuje obcięcie. Możliwe jest (choć nietypowe) posiadanie FK przeciwko unikalnemu ograniczeniu, które nie jest częścią PK ani kolumn tożsamości.
Rozwel

1
@Rozwel Znowu prawda, ale wydaje się rozsądnym założyć na podstawie pytania, że ​​nie ma żadnych unikalnych ograniczeń, biorąc pod uwagę, że PK istnieje tylko z powodu zrozumienia przez OP (poprawnego lub nie), że jest on wymagany przez bazę danych Azure SQL. Niezależnie od tego, jestem za redukcją dwuznaczności, więc dokonałem ponownej aktualizacji. Dzięki.
Solomon Rutzky

Posiadanie klucza obcego na stole nie jest niczym niezwykłym, a obecność ŻADNEGO klucza obcego zabrania TRUNCATE TABLE. Właśnie odkryłem to na własnej skórze dzisiaj, kiedy próbowałem uruchomić TRUNCATE TABLE na tabeli, która ma klucz obcy wymuszony względem dwóch innych kolumn w tabeli i unikalny indeks w tabeli obcej.
David A. Gray

83

Chociaż większość odpowiedzi sugeruje RESEED na 0, ale wiele razy musimy ponownie przejść do następnego dostępnego Id

declare @max int
select @max=max([Id])from [TestTable]
if @max IS NULL   //check when max is returned as null
  SET @max = 0
DBCC CHECKIDENT ('[TestTable]', RESEED,@max)

Spowoduje to sprawdzenie tabeli i zresetowanie do następnego ID.


2
To jedyna odpowiedź, która działa w 100% przypadków
Reversed Engineer

3
Nieco krótszy:declare @max int select @max=ISNULL(max([Id]),0) from [TestTable]; DBCC CHECKIDENT ('[TestTable]', RESEED, @max );
Guillermo Prandi

61

Próbowałem @anil shahsodpowiedzieć, a to zresetowało tożsamość. Ale kiedy wstawiono nowy wiersz, dostał identity = 2. Zamiast tego zmieniłem składnię na:

DELETE FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED, 0)
GO

Wtedy pierwszy wiersz otrzyma tożsamość = 1.



16

Mimo, że większość odpowiedzi sugeruje RESEEDsię 0, a gdy niektórzy widzą to jako wada dla TRUNCATEDtabel, Microsoft ma rozwiązanie, która wykluczaID

DBCC CHECKIDENT ('[TestTable]', RESEED)

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


1
Niestety to nieprawda. Właśnie sprawdziłem to dla serwera MS SQL 2014.
alehro

1
W rzeczywistości dotyczy to SQL 2014. Właśnie go przetestowałem i zadziałało dla mnie.
Daniel Dyson

2
Działa to niespójnie dla mnie w SQL 2012. Czasami używa następnej dostępnej, tak jak się spodziewałam, czasem wydaje się, że utknęła na starej wartości z tabeli. Określanie nasienia zawsze działa.
Dan Field

Nie działa dla mnie na SQL 2016 - po prostu pozostawia ziarno tożsamości bez zmian. Może kiedyś działało to dla mnie poprawnie, ale może to być również problem z palcami. Nie mogę go ponownie uruchomić
Reversed Engineer

Komunikat wskazuje sukces, Checking identity information: current identity value '[incorrect seed]', current column value '[correct seed]'.ale przy nowych wstawkach nadal używa niepoprawnego ziarna.
Denziloe

7

wydanie 2 polecenia może załatwić sprawę

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

pierwszy resetuje tożsamość do zera, a następny ustawi następną dostępną wartość - jacob


2
DBCC CHECKIDENT ('[TestTable]', RESEED) nie wysiewa ponownie do następnej dostępnej wartości
Atal Kishore

Jest to metoda stosowana przez RedGate Data Compare, gdy włączona jest opcja „Reseed tożsamość kolumny”. Przetestowałem go szeroko (mam na myśli kod SQL, a nie narzędzie RedGate) i działa niezawodnie. (Nie mam żadnego związku z RedGate poza tym, że od czasu do czasu jestem użytkownikiem ich wersji próbnych)
Reversed Engineer

6

@Jakub

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

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.


DBCC CHECKIDENT działa dopiero po usunięciu. Równie dobrze możesz użyć obcięcia. Jednak jeśli potrzebujesz reszty danych, nie używaj go. Również obcięcie nie podaje liczby usuniętych rekordów.
user763539,

6

Truncate tabela jest preferowana, ponieważ czyści rekordy, resetuje licznik i odzyskuje miejsce na dysku.

Deletei CheckIdentpowinny być używane tylko wtedy, gdy klucze obce uniemożliwiają obcięcie.


5

Zresetuj kolumnę tożsamości z nowym identyfikatorem ...

DECLARE @MAX INT
SELECT @MAX=ISNULL(MAX(Id),0) FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED,@MAX)

4

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.


15
Dotyczy to środowiska produkcyjnego, ale podczas opracowywania lubię pamiętać, że niektóre podmioty mają określony identyfikator, który jest wypełniany ze skryptu inicjującego. Ułatwia to poruszanie się po bazie danych podczas programowania.
Francois Botha

7
Odpowiedzi tego typu są całkowicie teoretyczne i rzadko odpowiadają rzeczywistym potrzebom. Co powiesz na to, żeby zamiast prać mózg ludzi, odpowiadasz na pytanie OP ...
Serj Sagan

1
Świetna historia stary. Moje twierdzenie jest następujące: jeśli chcesz określić wartość dla kolumny, nie wybieraj właściwości w kolumnie, która utrudnia robienie tego. Zapach kodu jest następujący: jeśli za każdym razem, gdy wstawiasz rekord do tabeli, określasz wartość dla kolumny tożsamości, nie masz kolumny tożsamości. Chodzi o to, aby serwer tworzył dla ciebie wartość. Więc jeśli zastąpisz ten czas, nie zyskasz nic za niezerowy koszt. Dobra robota nad argumentem ad hominem.
Ben Thul,

5
Z pewnością zgadzam się z twoim twierdzeniem. Patrząc na wartość nominalną, PO z pewnością robi to źle, ale być może istnieje głębsza potrzeba, aby nie stwierdzać w poście, że OP nie uznał za stosowne uzyskać odpowiedź na swoje pytanie. W związku z tym odpowiedz na pytanie i udziel „porady dotyczące zakazów” jako części odpowiedzi. Nawiasem mówiąc, nigdy nie atakowałem twojej postaci ... ad hominem oznacza, że ​​nazwałem cię głupcem czy coś ...
Serj Sagan

1
Chociaż z pewnością jest to prawda w większości przypadków, istnieją okoliczności, w których uzasadnione jest ponowne zasianie tabeli. Na przykład pracuję nad projektem typu greenfield, który musi rozpoczynać się od punktu, który z pewnością uwzględnia istniejące wiersze w poprzedniku, który zastępuje. Wysiew podczas rozwoju jest uzasadnionym przypadkiem użycia, IMO.
David A. Gray

3

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.


select * 
into #temp
From tableXYZ

set identity_insert tableXYZ ON

truncate table tableXYZ

alter table #temp drop column (nameOfIdentityColumn)

set identity_insert tableXYZ OFF

insert into tableXYZ
select * from #temp

3
Nie jest to całkowicie poprawne: SET IDENTITY_INSERT znajduje się w niewłaściwym miejscu. Nie omija TRUNCATE, lecz INSERT INTO (stąd tożsamość INSERT ). Ponadto należy go używać tylko wtedy, gdy dane muszą być przechowywane, w przeciwnym razie jest to bardzo nieefektywne w porównaniu z uruchomieniem pojedynczej instrukcji TRUNCATE.
Solomon Rutzky,

1
DBCC CHECKIDENT (<TableName>, reseed, 0)

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.


1

Użyj tej procedury składowanej:

IF (object_id('[dbo].[pResetIdentityField]') IS NULL)
  BEGIN
    EXEC('CREATE PROCEDURE [dbo].[pResetIdentityField] AS SELECT 1 FROM DUMMY');
  END
GO

SET  ANSI_NULLS ON
GO
SET  QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[pResetIdentityField]
  @pSchemaName NVARCHAR(1000)
, @pTableName NVARCHAR(1000) AS
DECLARE @max   INT;
DECLARE @fullTableName   NVARCHAR(2000) = @pSchemaName + '.' + @pTableName;

DECLARE @identityColumn   NVARCHAR(1000);

SELECT @identityColumn = c.[name]
FROM sys.tables t
     INNER JOIN sys.schemas s ON t.[schema_id] = s.[schema_id]
     INNER JOIN sys.columns c ON c.[object_id] = t.[object_id]
WHERE     c.is_identity = 1
      AND t.name = @pTableName
      AND s.[name] = @pSchemaName

IF @identityColumn IS NULL
  BEGIN
    RAISERROR(
      'One of the following is true: 1. the table you specified doesn''t have an identity field, 2. you specified an invalid schema, 3. you specified an invalid table'
    , 16
    , 1);
    RETURN;
  END;

DECLARE @sqlString   NVARCHAR(MAX) = N'SELECT @maxOut = max(' + @identityColumn + ') FROM ' + @fullTableName;

EXECUTE sp_executesql @stmt = @sqlString, @params = N'@maxOut int OUTPUT', @maxOut = @max OUTPUT

IF @max IS NULL
  SET @max = 0

print(@max)

DBCC CHECKIDENT (@fullTableName, RESEED, @max)
go

--exec pResetIdentityField 'dbo', 'Table'

Powracam do mojej odpowiedzi. Natknąłem się na dziwne zachowanie na serwerze SQL Server 2008 R2, o którym powinieneś wiedzieć.

drop table test01

create table test01 (Id int identity(1,1), descr nvarchar(10))

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

delete from test01

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

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.


1

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_CURRENTobecnie jest ustawiony na 1, tzn. Na początku był tylko jeden wiersz w tabeli.

DECLARE @maxID int = (SELECT MAX(ID) FROM dbo.Tbl)
;

IF @maxID IS NULL
    IF (SELECT IDENT_CURRENT('dbo.Tbl')) > 1
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 0)
    ELSE
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 1)
    ;
ELSE
    DBCC CHECKIDENT ('dbo.Tbl', RESEED, @maxID)
;

0

Do pełnego usunięcia wierszy i zresetowania liczby TOŻSAMOŚCI używam tego (SQL Server 2008 R2)

USE mydb

-- ##################################################################################################################
-- DANGEROUS!!!! USE WITH CARE
-- ##################################################################################################################

DECLARE
  db_cursor CURSOR FOR
    SELECT TABLE_NAME
      FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_TYPE = 'BASE TABLE'
       AND TABLE_CATALOG = 'mydb'

DECLARE @tblname VARCHAR(50)
SET @tblname = ''

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @tblname

WHILE @@FETCH_STATUS = 0
BEGIN
  IF CHARINDEX('mycommonwordforalltablesIwanttodothisto', @tblname) > 0
    BEGIN
      EXEC('DELETE FROM ' + @tblname)
      DBCC CHECKIDENT (@tblname, RESEED, 0)
    END

  FETCH NEXT FROM db_cursor INTO @tblname
END

CLOSE db_cursor
DEALLOCATE db_cursor
GO

0

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.


0

Podczas programowania starałem się to zrobić dla dużej liczby tabel, a to działa jak urok.

DBCC CHECKIDENT('www.newsType', RESEED, 1);
DBCC CHECKIDENT('www.newsType', RESEED);

Najpierw wymuszasz ustawienie go na 1, a następnie ustawiasz go na najwyższy indeks wierszy obecnych w tabeli. Szybka i łatwa reszta ideksu.


-2

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

W twoim przypadku odbuduj tylko indeks i nie martw się o utratę serii tożsamości, ponieważ jest to częsty scenariusz.


3
Wydaje mi się, że pomysł polega na usunięciu tylko niektórych nagrań.
Drumbeg

6
Jest to po prostu błędne - nie jest <i> ZAWSZE </i> lepiej używać obcinania, aw rzeczywistości jest lepsze tylko w niektórych, bardzo ograniczonych i specyficznych scenariuszach. Niebiosa zabraniają, aby ktoś postępował zgodnie z twoją radą, a następnie musiał wycofać się.
Thronk

1
@ Thronk Dlaczego sugerujesz, że TRUNCATEto uniemożliwiłoby ROLLBACKzachowanie się zgodnie z oczekiwaniami? ROLLBACK wciąż się wycofuje. Nawet jeśli DB jest ustawiony na BULK_LOGGED.
Solomon Rutzky

2
TRUNCATE to operacja DDL i nie jest ona rejestrowana w pliku dziennika. Chyba że jest to część transakcji (nie wymieniona nigdzie w pytaniu lub w tej odpowiedzi). Ilekroć ktoś mówi, że coś jest ZAWSZE prawdą, to całkiem bezpieczny zakład, że się mylą.
Thronk,

To jedyna odpowiedź, która zauważa różnicę w zachowaniu RESEED w zależności od tego, czy sekwencja była wcześniej używana, czy nie. Ponowne załadowanie tej samej wartości w wielu pustych tabelach, w których niektóre tabele były wcześniej zapełniane, spowoduje różne wartości początkowe dla pierwszego rekordu wstawionego do każdej tabeli.
simon coleman

-4

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.