Reset benih identitas setelah menghapus catatan di SQL Server


682

Saya telah memasukkan catatan ke tabel database SQL Server. Tabel memiliki kunci utama yang ditentukan dan seed identitas kenaikan otomatis diatur ke "Ya". Ini dilakukan terutama karena dalam SQL Azure, setiap tabel harus memiliki kunci utama dan identitas yang ditentukan.

Tetapi karena saya harus menghapus beberapa catatan dari tabel, seed identitas untuk tabel-tabel itu akan terganggu dan kolom indeks (yang dihasilkan secara otomatis dengan selisih 1) akan terganggu.

Bagaimana saya bisa mereset kolom identitas setelah saya menghapus catatan sehingga kolom memiliki urutan dalam urutan numerik naik?

Kolom identitas tidak digunakan sebagai kunci asing di mana pun dalam basis data.


4
"dalam SQL Azure" - "setiap tabel harus memiliki kunci utama" - true - "dan Identity Defined" - false. Identitas dan kunci utama adalah konsep ortogonal. Kolom identitas tidak harus menjadi PK tabel. Kunci utama tidak harus berupa kolom identitas.
Damien_The_Unbeliever

BAIK. Konsep saya bisa salah. Tapi sekarang saya telah mendefinisikan struktur tabel dengan PK dan Identity Seed. Jika saya harus menghapus beberapa baris, bagaimana saya bisa mereset Benih Identitas dalam urutan
kenaikan

29
Saya selalu berpendapat bahwa jika Anda peduli dengan nilai numerik aktual yang dihasilkan di kolom identitas, Anda menyalahgunakannya. Yang harus Anda pedulikan dengan kolom identitas adalah bahwa secara otomatis menghasilkan nilai unik (yay!) Dan Anda dapat menyimpan nilai-nilai ini dalam kolom numerik (bit ini hanya relevan untuk mendeklarasikan kolom untuk menyimpan nilai-nilai ini). Anda seharusnya tidak menunjukkannya kepada siapa pun, jadi tidak masalah apa nilai yang diambilnya.
Damien_The_Unbeliever

Anda dapat menggunakan cek cek dbcc seperti yang disebutkan lain tetapi harap dicatat bahwa kunci primer tidak wajib untuk sql db v12
Satya_MSFT

Jawaban:


1100

The DBCC CHECKIDENTperintah manajemen digunakan untuk me-reset counter identitas. Sintaks perintahnya adalah:

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

Contoh:

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

Itu tidak didukung di versi sebelumnya dari Azure SQL Database, tetapi didukung sekarang.


Harap dicatat bahwa new_reseed_valueargumen bervariasi di seluruh versi SQL Server sesuai dengan dokumentasi :

Jika baris ada dalam tabel, baris berikutnya dimasukkan dengan nilai new_reseed_value . Dalam versi SQL Server 2008 R2 dan sebelumnya, baris berikutnya yang disisipkan menggunakan new_reseed_value + nilai kenaikan saat ini.

Namun, saya menemukan informasi ini menyesatkan (hanya salah sebenarnya) karena perilaku yang diamati menunjukkan bahwa setidaknya SQL Server 2012 masih menggunakan new_reseed_value + logika nilai kenaikan saat ini. Microsoft bahkan bertentangan dengan yang Example Cditemukan di halaman yang sama:

C. Memaksa nilai identitas saat ini ke nilai baru

Contoh berikut memaksa nilai identitas saat ini di kolom AddressTypeID di tabel AddressType ke nilai 10. Karena tabel memiliki baris yang sudah ada, baris berikutnya yang dimasukkan akan menggunakan 11 sebagai nilai, yaitu, nilai kenaikan saat ini yang baru ditetapkan untuk nilai kolom plus 1.

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

Namun, ini semua meninggalkan opsi untuk perilaku yang berbeda pada versi SQL Server yang lebih baru. Saya kira satu-satunya cara untuk memastikan, sampai Microsoft menjernihkan hal-hal dalam dokumentasinya sendiri, adalah dengan melakukan tes yang sebenarnya sebelum digunakan.


24
Sintaksnya adalah ... DBCC CHECKIDENT ('[TestTable]', RESEED, 0) GO
Biki

2
Tampaknya DBCC CHECKIDENTdidukung pada rilis mendatang (V12 / Sterling): azure.microsoft.com/en-us/documentation/articles/… Meskipun, untuk situasi khusus ini, saya masih akan merekomendasikan TRUNCATE TABLE :)
Solomon Rutzky

1
Itu tidak bekerja untuk saya sampai "GO" berada di baris lain.
mrówa

1
Sintaksnya ditandai karena kata kunci GO di baris yang sama, saya tidak tahu mengapa. Bisakah Anda memindahkannya ke bawah garis. Saya menyalin dan menempelkan baris ini 50 kali dan sekarang saya harus kembali dan memperbaikinya.
AnotherDeveloper

4
Bekerja dengan sempurna untuk saya. Layak disebutkan bahwa saat menabur ulang sebuah tabel, jika Anda ingin me-reseed sehingga record pertama Anda adalah ID 1 maka perintah reseed harus me-reseed ke 0, sehingga record selanjutnya adalah ID 1.
Mike Upjohn

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

Di mana 0 adalah identitynilai Mulai


15
Jika tabel kosong, seperti jika Anda baru saja menelepon TRUNCATE, maka nilai seed baru harus menjadi nilai untuk digunakan berikutnya (yaitu 1 bukan 0). Jika tabel tidak kosong itu akan menggunakan tabel new_reseed_value + 1. MSDN
kjbartel

2
@ kjbartel, Anil, dan lainnya: tidak sesederhana hanya "jika tabelnya kosong". Dokumentasi tidak ada untuk kasus ketika tabel kosong karena DELETE, tidak TRUNCATE, dalam hal ini juga new_reseed+value + 1. Saya menulis posting tentang ini, menunjukkan perilaku aktual melalui beberapa tes, dan memperbarui dokumen yang sebenarnya (sekarang kita dapat karena itu berada di GitHub): Bagaimana DBID CHECKIDENT Benar-Benar Bekerja Ketika Mengatur Ulang Benih Identitas (RESEED)? .
Solomon Rutzky

87

Harus dicatat bahwa JIKA semua data dihapus dari tabel melalui DELETE(yaitu tidak ada WHEREklausa), maka selama a) izin untuk itu, dan b) tidak ada FK yang merujuk tabel (yang tampaknya menjadi kasus di sini), menggunakan TRUNCATE TABLEakan lebih disukai karena melakukan lebih efisien DELETE dan me-reset IDENTITYbenih pada saat yang sama. Detail berikut diambil dari halaman MSDN untuk TRUNCATE TABLE :

Dibandingkan dengan pernyataan DELETE, TRUNCATE TABLE memiliki kelebihan berikut:

  • Ruang log transaksi lebih sedikit digunakan.

    Pernyataan DELETE menghapus baris satu per satu dan mencatat entri dalam log transaksi untuk setiap baris yang dihapus. TRUNCATE TABLE menghapus data dengan mendeallocating halaman data yang digunakan untuk menyimpan data tabel dan hanya mencatat deallocations halaman dalam log transaksi.

  • Lebih sedikit kunci biasanya digunakan.

    Ketika pernyataan DELETE dieksekusi menggunakan kunci baris, setiap baris dalam tabel dikunci untuk dihapus. TRUNCATE TABLE selalu mengunci tabel (termasuk kunci skema (SCH-M)) dan halaman tetapi tidak setiap baris.

  • Tanpa kecuali, nol halaman tersisa di tabel.

    Setelah pernyataan DELETE dijalankan, tabel masih dapat berisi halaman kosong. Misalnya, halaman kosong di tumpukan tidak dapat dibatalkan alokasi tanpa setidaknya kunci tabel eksklusif (LCK_M_X). Jika operasi hapus tidak menggunakan kunci tabel, tabel (heap) akan berisi banyak halaman kosong. Untuk indeks, operasi penghapusan dapat meninggalkan halaman kosong, meskipun halaman-halaman ini akan dibatalkan dengan cepat oleh proses pembersihan latar belakang.

Jika tabel berisi kolom identitas, penghitung untuk kolom itu diatur ulang ke nilai seed yang ditentukan untuk kolom. Jika tidak ada seed yang didefinisikan, nilai default 1 digunakan. Untuk mempertahankan penghitung identitas, gunakan DELETE sebagai gantinya.

Jadi yang berikut ini:

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

Menjadi adil:

TRUNCATE TABLE [MyTable];

Silakan lihat TRUNCATE TABLEdokumentasi (ditautkan di atas) untuk informasi tambahan tentang pembatasan, dll.


8
Meskipun lebih efisien dalam keadaan yang benar, ini tidak selalu menjadi pilihan. Truncate tidak akan mengeksekusi pada tabel yang memiliki FK didefinisikan menentangnya. Bahkan ketika tidak ada catatan dependen, truncate akan gagal jika ada kendala. Juga terpotong membutuhkan izin ALTER di mana Hapus hanya perlu HAPUS.
Rozwel

3
@Rozwel Benar, tapi saya sudah memenuhi syarat jawaban saya yang menyatakan bahwa izin yang tepat harus ada. Juga, pertanyaannya secara spesifik menyatakan bahwa tidak ada FK. Namun, demi kejelasan, saya memperbarui untuk menentukan batasan "tidak ada FK". Terima kasih telah menunjukkannya.
Solomon Rutzky

1
hanya berdalih adalah bahwa setiap FK akan memblokir truncate. Dimungkinkan (meskipun tidak biasa) untuk memiliki FK terhadap batasan unik yang bukan bagian dari PK atau kolom identitas.
Rozwel

1
@Rozwel Sekali lagi benar, tetapi tampaknya masuk akal untuk berasumsi dari pertanyaan bahwa tidak ada kendala unik mengingat bahwa PK hanya ada karena pemahaman OP (benar atau tidak) yang diperlukan oleh Azure SQL Database. Apapun, saya semua untuk mengurangi ambiguitas jadi saya telah memperbarui lagi. Terima kasih.
Solomon Rutzky

Bukan hal yang aneh untuk memiliki kunci asing di atas meja, dan kehadiran kunci asing APAPUN melarang Tabel TrunCATE. Saya baru saja menemukan ini dengan cara yang sulit sebelumnya hari ini ketika saya mencoba menjalankan TRUNCATE TABLE pada tabel yang memiliki kunci asing yang diberlakukan terhadap dua kolom lain di tabel dan indeks unik di tabel asing.
David A. Gray

83

Meskipun sebagian besar jawaban menyarankan RESEED ke 0, tetapi seringkali kita perlu kembali ke Id berikutnya yang tersedia

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)

Ini akan memeriksa tabel dan mengatur ulang ke ID berikutnya.


2
Ini adalah satu-satunya jawaban yang bekerja 100% setiap waktu
Reversed Engineer

3
Sedikit lebih pendek:declare @max int select @max=ISNULL(max([Id]),0) from [TestTable]; DBCC CHECKIDENT ('[TestTable]', RESEED, @max );
Guillermo Prandi

61

Saya mencoba @anil shahsmenjawab dan itu mereset identitas. Tetapi ketika baris baru dimasukkan itu mendapat identity = 2. Jadi alih-alih saya mengubah sintaks menjadi:

DELETE FROM [TestTable]

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

Maka baris pertama akan mendapatkan identitas = 1.



16

Meskipun sebagian besar jawaban menyarankan RESEEDuntuk 0, dan sementara beberapa melihat ini sebagai sebuah cacat untuk TRUNCATEDtabel, Microsoft memiliki solusi yang tidak termasuk dalamID

DBCC CHECKIDENT ('[TestTable]', RESEED)

Ini akan memeriksa tabel dan mengatur ulang ke yang berikutnya ID. Ini telah tersedia sejak MS SQL 2005 hingga saat ini.

https://msdn.microsoft.com/en-us/library/ms176057.aspx


1
Sayangnya itu tidak benar. Baru saja memeriksa untuk server MS SQL 2014.
alehro

1
Sebenarnya, itu benar untuk SQL 2014. Saya baru saja mengujinya dan itu berhasil untuk saya.
Daniel Dyson

2
Ini bekerja secara tidak konsisten untuk saya di SQL 2012. Kadang-kadang menggunakan yang tersedia berikutnya seperti yang saya harapkan, kadang-kadang tampaknya terjebak pada nilai lama dari tabel. Menentukan benih selalu berhasil.
Dan Field

Tidak berfungsi untuk saya di SQL 2016 - itu hanya membiarkan benih identitas apa adanya. Ini mungkin bekerja dengan benar untuk saya satu kali, tetapi mungkin juga masalah jari saya. Tidak bisa berfungsi lagi
Reversed Engineer

Pesan menunjukkan keberhasilan,, Checking identity information: current identity value '[incorrect seed]', current column value '[correct seed]'.tetapi pada sisipan baru masih menggunakan seed yang salah.
Denziloe

7

mengeluarkan 2 perintah dapat melakukan triknya

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

yang pertama mengatur ulang identitas ke nol, dan selanjutnya akan mengaturnya ke nilai berikutnya yang tersedia - jacob


2
DBCC CHECKIDENT ('[TestTable]', RESEED) tidak melanjutkan untuk nilai yang tersedia berikutnya
Atal Kishore

Ini adalah metode yang digunakan oleh RedGate Data Compare ketika opsi "Reseed identity kolom" dihidupkan. Saya sudah mengujinya secara ekstensif (maksud saya dalam kode SQL, bukan pada alat RedGate), dan itu bekerja dengan andal. (Saya tidak memiliki hubungan dengan RedGate selain menjadi pengguna sesekali versi percobaan mereka)
Reversed Engineer

6

@ jacob

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

Berhasil bagi saya, saya hanya perlu menghapus semua entri terlebih dahulu dari tabel, lalu menambahkan di atas pada titik pemicu setelah dihapus. Sekarang setiap kali saya menghapus entri diambil dari sana.


DBCC CHECKIDENT hanya berfungsi setelah penghapusan. Anda mungkin juga menggunakan truncate. Namun jika Anda membutuhkan sisa data, jangan menggunakannya. Juga terpotong tidak memberikan catatan jumlah catatan dihapus.
user763539

6

Truncate tabel lebih disukai karena membersihkan catatan, mengatur ulang penghitung dan mendapatkan kembali ruang disk.

Deletedan CheckIdentharus digunakan hanya jika kunci asing mencegah Anda memotong.


5

Setel ulang kolom identitas dengan id baru ...

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

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

4

Ini adalah pertanyaan umum dan jawabannya selalu sama: jangan lakukan itu. Nilai identitas harus diperlakukan sebagai sewenang-wenang dan, dengan demikian, tidak ada urutan "benar".


15
Itu berlaku untuk lingkungan produksi, tetapi ketika sedang berkembang saya suka mengingat bahwa entitas tertentu memiliki ID tertentu, yang dihuni dari skrip penyemaian. Itu membuatnya lebih mudah untuk menavigasi melalui database saat dalam pengembangan.
Francois Botha

7
Jawaban seperti ini sepenuhnya teoretis dan jarang memenuhi kebutuhan dunia nyata. Bagaimana kalau alih-alih mencuci otak orang dengan dogma Anda, Anda jawab pertanyaan OP ...
Serj Sagan

1
Cerita keren, kawan. Pendapat saya adalah ini: jika Anda ingin menentukan nilai untuk sebuah kolom, jangan pilih properti pada kolom yang membuat melakukan hal itu sulit. Aroma kode adalah ini: jika setiap kali Anda memasukkan catatan ke dalam tabel Anda menentukan nilai untuk kolom identitas, Anda tidak memiliki kolom identitas. Inti identitas adalah membuat server membuat nilai untuk Anda. Jadi, jika Anda menimpa waktu itu, Anda tidak mendapatkan apa pun dengan biaya nol. Juga, kerja bagus pada argumen ad hominem.
Ben Thul

5
Saya tentu setuju dengan pendapat Anda. Melihat nilai nominalnya, OP tentu saja melakukan kesalahan, tetapi mungkin ada kebutuhan yang lebih dalam yang tidak dinyatakan dalam pos bahwa OP tidak menganggapnya relevan untuk menjawab pertanyaannya. Maka jawablah pertanyaan itu, dan berikan nasihat "lakukan dan jangan" sebagai bagian dari jawaban. Ngomong-ngomong, aku tidak pernah menyerang karaktermu ... ad hominem berarti aku menyebutmu bodoh atau apalah ...
Serj Sagan

1
Meskipun tentu saja benar dalam banyak kasus, ada keadaan di mana sah untuk menabur kembali sebuah tabel. Sebagai contoh, saya sedang mengerjakan proyek greenfield yang harus dimulai dari titik tertentu untuk menjelaskan baris yang ada di pendahulunya yang diganti. Peninjauan kembali selama pengembangan adalah kasus penggunaan yang sah, IMO.
David A. Gray

3

Jalankan skrip ini untuk mereset kolom identitas. Anda harus melakukan dua perubahan. Ganti tableXYZ dengan tabel apa pun yang Anda perlu perbarui. Juga, nama kolom identitas perlu dihapus dari tabel temp. Ini instan di atas meja dengan 35.000 baris & 3 kolom. Jelas, buat cadangan tabel dan coba ini dulu di lingkungan pengujian.


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
Ini tidak sepenuhnya benar: SET IDENTITY_INSERT berada di tempat yang salah. Itu tidak pergi di sekitar TRUNCATE, itu pergi di sekitar INSERT INTO (maka identitas_ INSERT ). Juga, ini akan digunakan hanya ketika data perlu disimpan, yang lain itu sangat tidak efisien dibandingkan dengan hanya menjalankan pernyataan TRUNCATE tunggal.
Solomon Rutzky

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

Ini akan menetapkan nilai identitas saat ini ke 0.

Saat memasukkan nilai berikutnya, nilai identitas akan bertambah menjadi 1.


1

Gunakan prosedur tersimpan ini:

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'

Hanya meninjau kembali jawaban saya. Saya menemukan perilaku aneh di sql server 2008 r2 yang harus Anda waspadai.

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

Pilih pertama menghasilkan 0, Item 1 .

Yang kedua menghasilkan 1, Item 1. Jika Anda menjalankan pengaturan ulang tepat setelah tabel dibuat, nilai selanjutnya adalah 0. Jujur, saya tidak terkejut Microsoft tidak bisa memperbaiki masalah ini. Saya menemukannya karena saya memiliki file skrip yang mengisi tabel referensi yang kadang-kadang saya jalankan setelah saya membuat kembali tabel dan kadang-kadang ketika tabel sudah dibuat.


1

Saya menggunakan skrip berikut untuk melakukan ini. Hanya ada satu skenario di mana ia akan menghasilkan "kesalahan", yaitu jika Anda telah menghapus semua baris dari tabel, dan IDENT_CURRENTsaat ini diatur ke 1, yaitu hanya ada satu baris dalam tabel untuk memulai.

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

Untuk baris DELETE lengkap dan setel ulang jumlah IDENTITAS, saya menggunakan ini (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

Pemasangan kembali ke 0 tidak terlalu praktis kecuali Anda membersihkan meja secara keseluruhan.

bijaksana jawaban yang diberikan oleh Anthony Raymond sempurna. Dapatkan max dari kolom identitas terlebih dahulu, lalu seed dengan max.


0

Saya sudah mencoba menyelesaikan ini untuk sejumlah besar tabel selama pengembangan, dan ini berfungsi sebagai pesona.

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

Jadi, pertama-tama Anda memaksakannya untuk diatur ke 1, lalu Anda mengaturnya ke indeks tertinggi dari baris yang ada di tabel. Sisa idex yang cepat dan mudah.


-2

Itu selalu lebih baik untuk menggunakan TRUNCATE bila memungkinkan daripada menghapus semua catatan karena tidak menggunakan ruang log juga.

Jika kita perlu menghapus dan perlu mengatur ulang seed, selalu ingat bahwa jika tabel tidak pernah diisi dan Anda menggunakan DBCC CHECKIDENT('tablenem',RESEED,0) maka record pertama akan mendapatkan identitas = 0 seperti yang dinyatakan pada dokumentasi msdn

Dalam kasus Anda, buat ulang indeks dan jangan khawatir kehilangan rangkaian identitas karena ini adalah skenario umum.


3
Kedengarannya bagi saya seperti idenya adalah hanya menghapus beberapa catatan.
Drumbeg

6
Ini benar-benar salah - Tidak <i> SELALU </i> lebih baik menggunakan truncate dan, pada kenyataannya, hanya lebih baik dalam beberapa skenario yang sangat terbatas dan spesifik. Surga melarang seseorang untuk mengikuti saran Anda dan kemudian perlu kembalikan.
Thronk

1
@Thronk Mengapa Anda menyiratkan bahwa TRUNCATEakan mencegah ROLLBACKberperilaku seperti yang diharapkan? ROLLBACK masih bergulir. Bahkan jika DB diatur ke BULK_LOGGED.
Solomon Rutzky

2
TRUNCATE adalah operasi DDL dan tidak masuk file log. Kecuali itu adalah bagian dari transaksi (tidak disebutkan di mana pun dalam pertanyaan atau dalam jawaban ini). Setiap kali ada yang mengatakan sesuatu SELALU benar, itu taruhan yang cukup aman bahwa mereka salah.
Thronk

Ini adalah satu - satunya jawaban yang mencatat ada perbedaan dalam perilaku RESEED tergantung pada apakah urutan sebelumnya digunakan atau tidak. Pengembalian nilai yang sama di beberapa tabel kosong , di mana beberapa tabel sebelumnya dihuni, akan menghasilkan nilai awal yang berbeda untuk catatan pertama dimasukkan ke dalam setiap tabel.
simon coleman

-4

Pertama: Spesifikasi Identitas Hanya: "Tidak" >> Simpan Proyek Jalankan Basis Data

Setelah itu: Spesifikasi Identitas Hanya: "YA" >> Simpan Proyek Jalankan Basis Data

ID Database Anda, PK Mulai dari 1 >>

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.