2010-05-27 3 views
13

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

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

+0

'DBCC CHECKIDENT ('tablename', RESEED)' http://stackoverflow.com/a/14445413/618186 – guanome

ответ

21

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

DBCC CHECKIDENT('myTable', RESEED, 24999) 

Таким образом, в комбинации, вы должны закончить с somethink как этот

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 

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

+1

Есть ли способ сделать это для каждой таблицы автоматически? – Earlz

+0

+1, но integer не является типом данных сервера sql, поэтому используйте: 'DECLARE @maxVal INT' и для заполнения переменной используйте:' SELECT @maxVal = ISNULL (max (ID), 0) +1 из mytable' –

+0

@KM хорошее замечание по проверке ISNULL, но «integer» распознается SQL Server 2008 – Earlz

9

ответ Томми правильно, но если я читаю documentation право это может быть упрощена просто:

DBCC CHECKIDENT ('myTable') 

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

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

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

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

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

и даже более автоматически ко всем таблицам: «Exec sp_MSforeachtable» DBCC CHECKIDENT (''? '') «' – Aristos

0

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

случаи Откат -

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

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