Скидання автоматичного збільшення в SQL Server після видалення


265

Я видалив деякі записи з таблиці в базі даних SQL Server. Тепер ідентифікатор переходить з 101 до 1200. Я хочу видалити записи ще раз, але я хочу, щоб ідентифікатори повернулися до 102. Чи є спосіб це зробити на SQL Server?


46
Будь ласка, не кажіть "Не робіть цього". Я ненавиджу, коли я запитую, як щось зробити, і все, що я отримую, - це ні. Так, скидання посвідчення може спричинити зовнішні ключові проблеми, але лише якщо ви не знаєте відповідної бази даних та програми. Існують дуже вагомі причини для скидання особи після планового видалення - їх називають Аудиторами. Аудитори ненавидять бачити прогалини, тому заповнюйте їх, робіть це контрольовано і стежте за тим, щоб збереглися закордонні ключові протипоказання.

6
@spyder, чи знали ви, що у вас з'являться прогалини, якщо вставка запису буде повернута не тільки для видалення? Ви не можете уникнути прогалин з автоматичним збільшенням, і це нерозумно намагатися. Я працював в аудиторському агентстві, і компетентні аудитори можуть їм це пояснити. Далі, якщо у вас є відповідні таблиці аудиту, вони можуть бачити, що сталося з цими записами. Або якщо з юридичних причин не повинно бути жодних прогалин (таких випадків небагато), тоді лише некомпетентний розробник використовує автоматичне підвищення, і аудитори справедливо засмучуються.
HLGEM

Відповіді:


454

Запустіть таку команду, щоб повторно переставити mytable, починаючи з 1:

DBCC CHECKIDENT (mytable, RESEED, 0)

Про це читайте в «Книгах на лінії» (довідка BOL, SQL). Також будьте обережні, щоб у вас не було записів, вищих за насіння, яке ви встановлюєте.


4
... тому що ідентифікатори цих записів будуть щасливо повторно використані, що спричинить поганий безлад.
nalply

3
Власне, для того, щоб почати посвідчення особи з 1, вам потрібно використовувати 0: DBCC CHECKIDENT (mytable, RESEED, 0)
Райан Лунді

7
"DBCC CHECKIDENT (ім'я таблиці)" встановлює насіння найвищою ідентичністю в таблиці, ніж вам не потрібно "бути обережним"
user1027167

4
@ user1027167 Ні, ваша відповідь не працювала для мене. Він збільшувався на найвищому ідентифікаторі, який він внутрішньо зберігав. Мені довелося явно використовувати "RESEED, 18" в моєму випадку, щоб отримати "19" як наступний ідентифікатор. Без цього він щасливо збільшувався на "29".
Маттіс Колі

DBCC CHECKIDENT (ім'я таблиці) змінює насіння лише у тому випадку, якщо значення ідентичності нижче максимального значення у стовпці. Отже, якщо значення ідентичності вже більше, як у випадку @MatthisKohli, потрібно викликати явну повторну перевірку.
Мартін

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

якщо число = 0, то в наступному вставці поле автоматичного збільшення буде містити значення 1

якщо число = 101, то в наступному вставці поле автоматичного збільшення буде містити значення 102


Деякі додаткові відомості ... Можуть бути корисними Вам

Перед тим, як надати автоматичний приріст numberу вищезазначеному запиті, ви повинні переконатися, що стовпець автоматичного збільшення вашої існуючої таблиці містить значення менше number.

Щоб отримати максимальне значення стовпця (ім'я стовпця) з таблиці (table1), ви можете використовувати наступний запит

 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 Документи кажуть, "якщо поточне значення ідентичності для таблиці менше максимального значення ідентичності, що зберігається у стовпці ідентичності"; що не охоплює очищення після видалення даних (повторне використання id - часто погана ідея). Підтверджено в SQL 2008
користувач423430

1
Найкраща систематична і автоматична відповідь. Браво!
Мехді Хадмелу

11

Якщо ви використовуєте MySQL, спробуйте це:

ALTER TABLE tablename AUTO_INCREMENT = 1

3
Це відповідь для MySQL. OP запитує про MSSQL.
реформовано

питання стосується MS SQL Server
Saher Ahwal

6

Видалення та повторне використання всіх таблиць у базі даних.

    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)

Але в ОП сказали, що "видалено деякі записи", які можуть бути не всіма, тому значення 0 не завжди є правильним. Інша відповідь запропонувала автоматично знайти максимальне значення струму та перевстановити його, але це зіткнеться з проблемою, якщо в таблиці немає записів, і таким чином max () поверне NULL. Коментар пропонується використовувати просто

DBCC CHECKIDENT (mytable)

скинути значення, але інший коментар правильно вказав, що це лише збільшує значення до максимуму, що вже є в таблиці; це не зменшить значення, якщо воно вже вище максимального в таблиці, що саме хотіла зробити ОП.

Краще рішення поєднує ці ідеї. Перший CHECKIDENT скидає значення до 0, а другий повертає його до найвищого значення, що знаходиться в таблиці, якщо у таблиці є записи:

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

Як зазначається кілька коментарів, переконайтеся, що в інших таблицях немає сторонніх ключів, що вказують на видалені записи. Інакше ці іноземні ключі будуть вказувати на записи, які ви створюєте після повторної повторної роботи таблиці, що майже точно не те, що ви мали на увазі.


4

Я хочу додати цю відповідь, оскільки- DBCC CHECKIDENTAssach викличе проблеми з продуктом, коли ви використовуєте схеми для таблиць. Використовуйте це, щоб бути впевненим:

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

Якщо ви хочете перевірити успішність операції, використовуйте

SELECT IDENT_CURRENT(@Table);

який слід вивести 0у наведеному вище прикладі.


1

Ти взагалі не хочеш цього робити. Повторне дослідження може створити проблеми з цілісністю даних. Це дійсно лише для використання в системах розробки, де ви стираєте всі тестові дані і починаєте заново. Він не повинен використовуватися у виробничій системі у випадку, якщо всі пов'язані записи не були видалені (не кожна таблиця, яка має бути у зовнішньому ключі, є!). Ви можете створити безлад, роблячи це, особливо якщо ви хочете робити це регулярно після кожного видалення. Неприємно турбуватися про прогалини у ваших значеннях поля ідентичності.


6
Я не буду його використовувати постійно, і це було лише на тестовому db.
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
Дякуємо за цей фрагмент коду, який може надати деяку обмежену, негайну допомогу. Належне пояснення було б значно поліпшити свою довгострокову цінність , показуючи , чому це хороше рішення проблеми, і зробить його більш корисним для читачів майбутніх з іншими подібними питаннями. Будь ласка, відредагуйте свою відповідь, щоб додати пояснення, включаючи зроблені вами припущення.
Goodbye StackExchange
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.