Reset AutoIncrement di SQL Server setelah Hapus

266

Saya telah menghapus beberapa catatan dari tabel dalam database SQL Server. Sekarang ID berubah dari 101 menjadi 1.200. Saya ingin menghapus catatan lagi, tapi saya ingin ID kembali ke 102. Apakah ada cara untuk melakukan ini di SQL Server?

jumbojs
sumber
46
Tolong jangan katakan "Jangan lakukan itu". Saya benci ketika saya bertanya bagaimana melakukan sesuatu dan semua yang saya dapatkan adalah jangan. Ya, mengatur ulang identitas dapat menyebabkan masalah kunci asing tetapi hanya jika Anda tidak mengetahui database dan program Anda. Ada alasan yang sangat bagus untuk mengatur ulang identitas setelah penghapusan yang dijadwalkan - mereka disebut Auditor. Auditor tidak suka melihat celah jadi isilah mereka, lakukan dengan cara yang terkendali dan pastikan batasan kunci asing dipertahankan.
6
@ spyder, tahukah Anda bahwa Anda akan memiliki celah jika sisipan catatan diputar kembali bukan hanya untuk dihapus? Anda tidak dapat menghindari celah dengan peningkatan otomatis dan itu bodoh untuk mencoba. Saya telah bekerja untuk lembaga audit dan auditor yang kompeten dapat menjelaskan hal ini kepada mereka. Lebih lanjut jika Anda memiliki tabel audit yang tepat, mereka dapat melihat apa yang terjadi pada catatan tersebut. Atau jika tidak boleh ada kesenjangan karena alasan hukum (ada beberapa kasus dalam hal ini), maka hanya pengembang yang tidak kompeten yang akan menggunakan peningkatan otomatis dan auditor benar-benar kecewa.
HLGEM

Jawaban:

455

Keluarkan perintah berikut untuk me-reseed mytable untuk memulai pada 1:

DBCC CHECKIDENT (mytable, RESEED, 0)

Baca tentang itu di Books on Line (BOL, bantuan SQL). Juga berhati-hatilah karena Anda tidak memiliki catatan yang lebih tinggi dari benih yang Anda atur.

Robert Wagner
sumber
4
... karena id dari catatan ini akan dengan senang hati digunakan kembali, menyebabkan kekacauan yang buruk.
nalply
3
Sebenarnya, untuk memulai ID pada 1, Anda harus menggunakan 0: DBCC CHECKIDENT (mytable, RESEED, 0)
Ryan Lundy
7
"DBCC CHECKIDENT (table_name)" mengatur seed ke identitas tertinggi dalam tabel, daripada Anda tidak harus "hati-hati"
user1027167
4
@ user1027167 Tidak, jawaban Anda tidak berfungsi untuk saya. Itu terus bertambah pada ID tertinggi yang disimpannya secara internal. Saya harus secara eksplisit menggunakan "RESEED, 18" dalam kasus saya untuk mendapatkan "19" sebagai ID berikutnya. Tanpa itu terus bertambah dengan senang hati pada "29".
Matthis Kohli
DBCC CHECKIDENT (table_name) hanya mengubah seed jika nilai identitas lebih rendah dari nilai maksimum di kolom. Jadi jika nilai identitas sudah lebih besar seperti kasus @MatthisKohli, resume eksplisit harus dipanggil.
Martheen
82
DBCC CHECKIDENT('databasename.dbo.tablename', RESEED, number)

jika angka = 0 maka pada sisipan berikutnya bidang kenaikan otomatis akan berisi nilai 1

jika angka = 101 maka pada sisipan berikutnya bidang kenaikan otomatis akan berisi nilai 102


Beberapa info tambahan ... Semoga bermanfaat bagi Anda

Sebelum memberikan kenaikan otomatis numberdalam kueri di atas, Anda harus memastikan kolom kenaikan otomatis tabel yang ada berisi nilai lebih sedikit dari itu number.

Untuk mendapatkan nilai maksimum kolom (nama_kolom) dari tabel (table1), Anda bisa menggunakan kueri berikut

 SELECT MAX(column_name) FROM table1
Fathah Rehman P
sumber
37

semi-idiot-bukti:

declare @max int;  
select @max = max(key) from table;  
dbcc checkident(table,reseed,@max)

http://sqlserverplanet.com/tsql/using-dbcc-checkident-to-reseed-a-table-after-delete

user423430
sumber
1
"DBCC CHECKIDENT (table_name)" melakukan hal yang sama (mungkin tanpa kondisi balapan)
user1027167
2
@ user1027167 Dokumen mengatakan 'jika nilai identitas saat ini untuk sebuah tabel kurang dari nilai identitas maksimum yang disimpan di kolom identitas'; yang tidak mencakup pembersihan setelah data dihapus (menggunakan kembali id ​​- seringkali merupakan ide yang buruk). Diverifikasi pada SQL 2008
user423430
1
Jawaban sistematis dan otomatis terbaik. Bravo!
Mehdi Khademloo
11

Jika Anda menggunakan MySQL, coba ini:

ALTER TABLE tablename AUTO_INCREMENT = 1
xaa
sumber
3
Ini jawaban untuk MySQL. OP bertanya tentang MSSQL.
direformasi
pertanyaannya adalah tentang MS SQL Server
Saher Ahwal
6

Hapus dan Kembalikan semua tabel dalam database.

    USE [DatabaseName]
    EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"       -- Disable All the constraints
    EXEC sp_MSForEachTable "DELETE FROM ?"    -- Delete All the Table data
    Exec sp_MSforeachtable 'DBCC CHECKIDENT(''?'', RESEED, 0)' -- Reseed All the table to 0
    Exec sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"  -- Enable All  the constraints back

-- You may ignore the errors that shows the table without Auto increment field.
BMG
sumber
6

Saya menemukan jawabannya. Nya:

 DBCC CHECKIDENT ('tablename', RESEED, newseed)
jumbojs
sumber
4

Berdasarkan jawaban yang diterima, bagi mereka yang mengalami masalah serupa, dengan kualifikasi skema penuh:

( [MyDataBase].[MySchemaName].[MyTable]) ... menghasilkan kesalahan, Anda harus berada dalam konteks DB itu

Artinya, berikut ini akan menimbulkan kesalahan:

DBCC CHECKIDENT ([MyDataBase].[MySchemaName].[MyTable], RESEED, 0)

Lampirkan nama tabel yang sepenuhnya memenuhi syarat dengan satu kutipan saja:

DBCC CHECKIDENT ('[MyDataBase].[MySchemaName].[MyTable]', RESEED, 0)
pengguna919426
sumber
4

Beberapa jawaban merekomendasikan penggunaan pernyataan seperti ini:

DBCC CHECKIDENT (mytable, RESEED, 0)

Tetapi OP mengatakan "menghapus beberapa catatan", yang mungkin tidak semuanya, jadi nilai 0 tidak selalu yang benar. Jawaban lain menyarankan secara otomatis menemukan nilai maksimum saat ini dan me-reseeding ke yang itu, tetapi itu akan bermasalah jika tidak ada catatan dalam tabel, dan dengan demikian max () akan mengembalikan NULL. Sebuah komentar disarankan hanya menggunakan

DBCC CHECKIDENT (mytable)

untuk mengatur ulang nilai, tetapi komentar lain dengan benar menyatakan bahwa ini hanya meningkatkan nilai ke maksimum yang sudah ada dalam tabel; ini tidak akan mengurangi nilai jika sudah lebih tinggi dari maksimum dalam tabel, yang mana OP ingin lakukan.

Solusi yang lebih baik menggabungkan ide-ide ini. CHECKIDENT pertama me-reset nilai ke 0, dan yang kedua me-reset ke nilai tertinggi saat ini dalam tabel, jika ada catatan dalam tabel:

DBCC CHECKIDENT (mytable, RESEED, 0)
DBCC CHECKIDENT (mytable)

Seperti yang ditunjukkan beberapa komentar, pastikan tidak ada kunci asing di tabel lain yang menunjuk ke catatan yang dihapus. Kalau tidak, kunci asing itu akan menunjuk ke catatan yang Anda buat setelah me-reseed tabel, yang hampir pasti bukan yang ada dalam pikiran Anda.

Michael Rodby
sumber
4

Saya ingin menambahkan jawaban ini karena DBCC CHECKIDENT-approach akan menghasilkan masalah ketika Anda menggunakan skema untuk tabel. Gunakan ini untuk memastikan:

DECLARE @Table AS NVARCHAR(500) = 'myschema.mytable';
DBCC CHECKIDENT (@Table, RESEED, 0);

Jika Anda ingin memeriksa keberhasilan operasi, gunakan

SELECT IDENT_CURRENT(@Table);

yang seharusnya ditampilkan 0dalam contoh di atas.

Alexander Schmidt
sumber
1

Anda tidak ingin melakukan ini secara umum. Ditinjau ulang dapat menyebabkan masalah integritas data. Ini benar-benar hanya untuk digunakan pada sistem pengembangan di mana Anda memusnahkan semua data uji dan memulai dari awal. Itu tidak boleh digunakan pada sistem produksi jika semua catatan terkait belum dihapus (tidak setiap tabel yang harus dalam hubungan kunci asing adalah!). Anda dapat membuat kekacauan melakukan ini dan terutama jika Anda bermaksud melakukannya secara teratur setelah setiap penghapusan. Adalah ide yang buruk untuk khawatir tentang kesenjangan dalam nilai bidang identitas Anda.

HLGEM
sumber
6
Saya tidak akan menggunakannya sepanjang waktu dan itu hanya pada tes db.
jumbojs
0

Bagaimana dengan ini?

ALTER TABLE `table_name`
  MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;

Ini adalah cara cepat dan sederhana untuk mengubah kenaikan otomatis ke 0 atau angka apa pun yang Anda inginkan. Saya menemukan ini dengan mengekspor database dan membaca kode sendiri.

Anda juga dapat menulisnya seperti ini untuk menjadikannya solusi satu baris:

ALTER TABLE `table_name` MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;
Victor Resnov
sumber
1
Terima kasih atas cuplikan kode ini, yang mungkin memberikan bantuan terbatas dan segera. Sebuah penjelasan yang tepat akan sangat meningkatkan nilai jangka panjang dengan menunjukkan mengapa ini adalah solusi yang baik untuk masalah ini, dan akan membuatnya lebih bermanfaat untuk pembaca masa depan dengan lainnya, pertanyaan-pertanyaan serupa. Harap edit jawaban Anda untuk menambahkan beberapa penjelasan, termasuk asumsi yang Anda buat.
Selamat tinggal StackExchange