Подтвердить что ты не робот

Как автоматически reseed после использования identity_insert?

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

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

4b9b3361

Ответ 1

Используйте информацию в этой ссылке в сочетании с функцией SQL, которая получает максимальную (RID) из каждой таблицы, которая вам нужна reset. Например, если вы хотите запустить первичное ключевое семя на 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 

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

Ответ 2

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

DBCC CHECKIDENT ('myTable')

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

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

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

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

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

Ответ 3

Возможно, самый простой способ (как сумасшедший, как это звучит и как вонючий, как он выглядит) - просто запустить 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 (''?'')'

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

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

Ответ 4

Отказоустойчивые случаи -

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

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

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

И, коды:

DBCC CHECKIDENT (teste_sequencial)

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

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