รีเซ็ต AutoIncrement ใน SQL Server หลังจากลบ


265

ฉันได้ลบบางระเบียนออกจากตารางในฐานข้อมูล SQL Server ตอนนี้ ID เปลี่ยนจาก 101 เป็น 1200 ฉันต้องการลบระเบียนอีกครั้ง แต่ฉันต้องการให้ ID กลับไปที่ 102 มีวิธีทำเช่นนี้ใน SQL Server หรือไม่


46
กรุณาอย่าพูดว่า "อย่าทำ" ฉันเกลียดเมื่อฉันถามว่าจะทำอะไรและทุกอย่างที่ฉันได้รับคือ ใช่การรีเซ็ตตัวตนอาจทำให้เกิดปัญหากับ foreign key แต่ถ้าคุณไม่ทราบฐานข้อมูลและโปรแกรมของคุณ มีเหตุผลที่ดีมากสำหรับการรีเซ็ตข้อมูลประจำตัวหลังจากการลบแบบกำหนดระยะเวลา - พวกเขาเรียกว่าผู้สอบบัญชี ผู้ตรวจสอบบัญชีเกลียดที่จะเห็นช่องว่างดังนั้นให้เติมลงในวิธีที่ถูกควบคุมและตรวจสอบให้แน่ใจว่ามีการรักษาข้อ จำกัด ที่สำคัญต่างประเทศ

6
@spyder คุณรู้หรือไม่ว่าคุณจะมีช่องว่างถ้ามีการยกเลิกการแทรกเรคคอร์ดไม่ใช่เพื่อลบ? คุณไม่สามารถหลีกเลี่ยงช่องว่างด้วยการสร้างอัตโนมัติและมันเป็นเรื่องโง่ที่จะลอง ฉันทำงานให้กับหน่วยงานตรวจสอบและผู้ตรวจสอบที่มีความสามารถสามารถอธิบายสิ่งนี้ให้พวกเขาได้ นอกจากนี้หากคุณมีตารางการตรวจสอบที่เหมาะสมพวกเขาสามารถเห็นสิ่งที่เกิดขึ้นกับบันทึกเหล่านั้น หรือหากไม่มีช่องว่างใด ๆ ด้วยเหตุผลทางกฎหมาย (มีบางกรณี) ผู้พัฒนาที่ไร้ความสามารถเท่านั้นที่จะใช้ระบบอัตโนมัติและผู้ตรวจสอบบัญชีจะอารมณ์เสียอย่างถูกต้อง
HLGEM

คำตอบ:


454

ออกคำสั่งต่อไปนี้เพื่อให้ mytable เริ่มต้นใหม่ที่ 1:

DBCC CHECKIDENT (mytable, RESEED, 0)

อ่านเกี่ยวกับมันใน Books on Line (BOL, SQL help) นอกจากนี้ควรระวังว่าคุณไม่มีบันทึกที่สูงกว่าเมล็ดพันธุ์ที่คุณตั้งค่า


4
... เพราะรหัสของบันทึกเหล่านี้จะถูกนำกลับมาใช้ใหม่อย่างมีความสุขทำให้เกิดความยุ่งเหยิง
nalply

3
ที่จริงแล้วเพื่อที่จะเริ่ม ID ที่ 1 คุณต้องใช้ 0: DBCC CHECKIDENT (mytable, RESEED, 0)
Ryan Lundy

7
"DBCC CHECKIDENT (table_name)" ตั้งค่าเมล็ดเป็นตัวตนสูงสุดในตารางกว่าที่คุณไม่จำเป็นต้อง "ระวัง"
user1027167

4
@ user1027167 ไม่คำตอบของคุณไม่เหมาะกับฉัน มันยังคงเพิ่มขึ้นใน ID สูงสุดที่มันบันทึกไว้ภายใน ฉันต้องใช้ "RESEED, 18" อย่างชัดเจนในกรณีของฉันเพื่อรับ "19" เป็นรหัสถัดไป หากไม่มีมันก็ยังคงเพิ่มขึ้นอย่างมีความสุขใน "29"
Matthis Kohli

DBCC CHECKIDENT (table_name)จะเปลี่ยนเมล็ดถ้าค่าตัวตนต่ำกว่าค่าสูงสุดในคอลัมน์ ดังนั้นหากค่าตัวตนที่ใหญ่กว่าเช่นกรณี @MatthisKohli ต้องมีการเรียกข้อมูลที่ชัดเจนใหม่
Martheen

82
DBCC CHECKIDENT('databasename.dbo.tablename', RESEED, number)

ถ้า number = 0 ดังนั้นในการแทรกครั้งถัดไปฟิลด์การเพิ่มอัตโนมัติจะมีค่า 1

ถ้า number = 101 ดังนั้นในส่วนถัดไปแทรกฟิลด์การเพิ่มอัตโนมัติจะมีค่า 102


บางข้อมูลเพิ่มเติมที่ ... อาจจะเป็นประโยชน์กับคุณ

ก่อนที่จะให้เพิ่มขึ้นโดยอัตโนมัติในการค้นหาข้างต้นคุณต้องให้แน่ใจว่าคอลัมน์ที่เพิ่มขึ้นรถยนต์ตารางที่มีอยู่ของคุณมีค่าน้อยกว่าที่numbernumber

ในการรับค่าสูงสุดของคอลัมน์ (column_name) จากตาราง (ตารางที่ 1) คุณสามารถใช้แบบสอบถามต่อไปนี้

 SELECT MAX(column_name) FROM table1

37

กึ่งงี่เง่า - หลักฐาน:

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


1
"DBCC CHECKIDENT (table_name)" ทำเช่นเดียวกัน (เป็นไปได้โดยไม่มีเงื่อนไขการแข่งขัน)
user1027167

2
@ user1027167 เอกสารบอกว่า 'หากค่าตัวตนปัจจุบันของตารางน้อยกว่าค่าตัวตนสูงสุดที่เก็บไว้ในคอลัมน์ข้อมูลประจำตัว'; ที่ไม่ครอบคลุมการล้างข้อมูลหลังจากลบข้อมูล (การใช้รหัสซ้ำอีกครั้ง - มักเป็นแนวคิดที่ไม่ดี) ตรวจสอบแล้วใน SQL 2008
user423430

1
คำตอบที่เป็นระบบและอัตโนมัติที่ดีที่สุด ไชโย!
Mehdi Khademloo


6

ลบและ Reseed ตารางทั้งหมดในฐานข้อมูล

    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.


4

ตามคำตอบที่ยอมรับสำหรับผู้ที่พบปัญหาที่คล้ายกันโดยมีคุณสมบัติแบบแผนเต็ม:

( [MyDataBase].[MySchemaName].[MyTable]) ... ส่งผลให้เกิดข้อผิดพลาดคุณต้องอยู่ในบริบทของฐานข้อมูลนั้น

นั่นคือสิ่งต่อไปนี้จะทำให้เกิดข้อผิดพลาด:

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

ใส่ชื่อตารางที่มีคุณสมบัติครบถ้วนด้วยเครื่องหมายคำพูดเดี่ยวแทน:

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

4

คำตอบหลายข้อแนะนำให้ใช้คำสั่งแบบนี้:

DBCC CHECKIDENT (mytable, RESEED, 0)

แต่ OP กล่าวว่า "ลบระเบียนบางส่วน" ซึ่งอาจไม่ใช่ทั้งหมดดังนั้นค่า 0 จึงไม่ใช่รายการที่ถูกต้องเสมอไป คำตอบอื่น ๆ ที่แนะนำให้ค้นหาค่าปัจจุบันสูงสุดโดยอัตโนมัติและดำเนินการกับค่านั้นใหม่ แต่จะพบปัญหาหากไม่มีระเบียนในตารางและ max () จะส่งกลับค่า NULL ความคิดเห็นที่แนะนำให้ใช้เพียง

DBCC CHECKIDENT (mytable)

เพื่อรีเซ็ตค่า แต่ความคิดเห็นอื่นระบุไว้อย่างถูกต้องว่านี่จะเป็นการเพิ่มค่าสูงสุดในตารางเท่านั้น สิ่งนี้จะไม่ลดค่าถ้ามันสูงกว่าค่าสูงสุดในตารางแล้วซึ่งเป็นสิ่งที่ OP ต้องการทำ

ทางออกที่ดีกว่ารวมความคิดเหล่านี้ CHECKIDENT แรกจะรีเซ็ตค่าเป็น 0 และอันดับที่สองจะรีเซ็ตเป็นค่าสูงสุดในตารางในกรณีที่มีระเบียนในตาราง:

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

ตามที่มีการแสดงความคิดเห็นหลายรายการตรวจสอบให้แน่ใจว่าไม่มีคีย์ต่างประเทศในตารางอื่น ๆ ที่ชี้ไปยังระเบียนที่ถูกลบ มิฉะนั้นคีย์ต่างประเทศเหล่านั้นจะชี้ไปที่ระเบียนที่คุณสร้างขึ้นหลังจากการป้อนข้อมูลในตารางซ้ำอีกครั้งซึ่งแทบจะไม่ใช่สิ่งที่คุณคิด


4

ฉันต้องการเพิ่มคำตอบนี้เพราะDBCC CHECKIDENT-approach จะทำให้เกิดปัญหาเมื่อคุณใช้ schema สำหรับตาราง ใช้สิ่งนี้เพื่อให้แน่ใจว่า:

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

หากคุณต้องการตรวจสอบความสำเร็จของการใช้งานให้ใช้

SELECT IDENT_CURRENT(@Table);

ซึ่งควรส่งออก0ในตัวอย่างข้างต้น


1

คุณไม่ต้องการทำสิ่งนี้โดยทั่วไป Reseed สามารถสร้างปัญหาความสมบูรณ์ของข้อมูล เป็นจริงเท่านั้นสำหรับใช้ในระบบการพัฒนาที่คุณเช็ดข้อมูลการทดสอบทั้งหมดและเริ่มต้นใหม่ ไม่ควรใช้กับระบบการผลิตในกรณีที่บันทึกที่เกี่ยวข้องทั้งหมดไม่ได้ถูกลบ (ไม่ใช่ทุกตารางที่ควรอยู่ในความสัมพันธ์กับคีย์ต่างประเทศคือ!) คุณสามารถสร้างความยุ่งเหยิงในการทำเช่นนี้และโดยเฉพาะอย่างยิ่งถ้าคุณตั้งใจทำอย่างสม่ำเสมอหลังจากลบทุกครั้ง มันเป็นความคิดที่ดีที่จะกังวลเกี่ยวกับช่องว่างในคุณค่าของตัวตนของคุณ


6
ฉันจะไม่ใช้มันตลอดเวลาและมันก็เป็นเพียงการทดสอบฐานข้อมูล
jumbojs

0

แล้วเรื่องนี้ล่ะ

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

นี่เป็นวิธีที่ง่ายและรวดเร็วในการเปลี่ยนการเพิ่มอัตโนมัติเป็น 0 หรือจำนวนที่คุณต้องการ ฉันคิดออกโดยการส่งออกฐานข้อมูลและอ่านรหัสด้วยตัวเอง

คุณสามารถเขียนแบบนี้เพื่อทำให้เป็นโซลูชันบรรทัดเดียว:

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

1
ขอขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือแบบ จำกัด และทันที คำอธิบายที่เหมาะสมมากจะเพิ่มมูลค่าในระยะยาวด้วยการแสดงเหตุผลนี้เป็นทางออกที่ดีในการแก้ไขปัญหาและจะทำให้มันมีประโยชน์มากขึ้นให้กับผู้อ่านในอนาคตกับอื่น ๆ คำถามที่คล้ายกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายรวมถึงข้อสมมติฐานที่คุณทำ
ลา StackExchange
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.