Как автоматически перезаряжать после использования identity_insert? - PullRequest
17 голосов
/ 27 мая 2010

Я недавно мигрировал из базы данных PostgreSQL в базу данных SQL Server. Чтобы переключить данные, мне нужно было включить IDENTITY_INSERT. Приходите, чтобы узнать, что я получаю всевозможные странные ошибки из-за дублирования значений идентификаторов (которые устанавливаются в качестве первичных ключей) при выполнении вставки в любую из таблиц.

У меня довольно много столов. Что было бы самым простым способом автоматического повторного заполнения идентификатора каждой таблицы, чтобы она была после max(RID)?

Ответы [ 4 ]

28 голосов
/ 27 мая 2010

Используйте информацию в этой ссылке в сочетании с функцией SQL, которая получает максимальное значение (RID) для каждой таблицы, которую необходимо сбросить. Например, если вы хотите запустить начальный начальный ключ с 25000, используйте код ниже (StartSeedValue - 1)

DBCC CHECKIDENT('myTable', RESEED, 24999)

Так что в комбинации вы должны получить что-то вроде этого

DECLARE @maxVal INT
SELECT @maxVal = ISNULL(max(ID),0)+1 from mytable
DBCC CHECKIDENT('mytable', RESEED, @maxVal)

Извините за псевдокод, некоторое время назад я написал функцию SQL:)

EDIT:

Спасибо за улов, поменял INTEGER на INT

USE YourDBName
GO 
SELECT *
FROM sys.Tables
GO 

Это даст вам список всех пользовательских таблиц в базе данных. Используйте этот запрос в качестве «цикла», и это должно позволить сбросить начальные числа во всех таблицах.

15 голосов
/ 02 ноября 2015

Томми ответ правильный, но если я читаю документацию правильно, это можно упростить до:

DBCC CHECKIDENT ('myTable')

Согласно документации:

Если текущее значение идентификатора для таблицы меньше максимального Значение идентификатора хранится в столбце идентификаторов, оно сбрасывается с помощью максимальное значение в столбце идентификаторов.

Это избавляет вас от необходимости искать максимальный идентификатор вручную и поддерживается начиная с SQL Server 2005.

Это должно работать в оригинальном случае OP. Однако в документации упоминаются два случая, когда это не сработает, и вам придется обратиться к решению Томми с поиском максимального значения идентификатора вручную:

  • Текущее значение идентификатора больше максимального значения в Таблица.
  • Все строки удалены из таблицы.
1 голос
/ 02 ноября 2016

Пожалуй, самый простой способ (как бы безумно это ни звучало и как ни воняло на код), это просто запустить DBCC CHECKIDENT дважды так:

-- sets all the seeds to 1
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'', RESEED, 1)'

-- run it again to get MSSQL to figure out the MAX/NEXT seed automatically
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')'

Готово.

Если хотите, вы можете запустить его еще раз, чтобы увидеть, на что были установлены все семена:

-- run it again to display what the seeds are now set to
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')'

Это просто творческий способ воспользоваться комментариями из документации:

Если текущее значение идентификатора для таблицы меньше максимального Значение идентификатора хранится в столбце идентификаторов, оно сбрасывается с помощью максимальное значение в столбце идентификаторов.

0 голосов
/ 29 ноября 2016

Откат чехлов -

Я тестирую в своей базе данных и работаю, только если я использую этот код, указанный здесь ранее (с модификацией +1 - нам это не нужно).

DECLARE @maxVal INT
SELECT @maxVal = ISNULL(max(codsequencia),0) from teste_sequencial
DBCC CHECKIDENT(teste_sequencial, RESEED, @maxVal)

Обратите внимание: если вы поставите +1 после части 'ISNULL', следующий столбец идентификатора будет прыгать +1, например - текущий столбец 10, после кода следующий будет 11, если вы используете +1 после isnull , будет + 12.

И, коды:

DBCC CHECKIDENT (teste_sequencial)

Exec sp_MSforeachtable 'DBCC CHECKIDENT(''?'')'

У меня вообще не работало в случаях отката. Если вы откроете транзакцию и выполните откат, повторное заполнение начнется с последнего номера, использованного в транзакции.

...