Sql-Server

DBCC CHECKIDENT 行為不一致

  • July 12, 2019

我有一個腳本,有時需要在剛剛創建所有表的新數據庫上執行,有時需要在現有數據庫上執行。我有一個腳本來清除表並使用最新版本的參考表進行更新,以便可以更新這個腳本並將其儲存在源儲存庫中,以便在任何需要執行它的數據庫伺服器上使用。

如果這是在新數據庫上第一次執行,則 DBCC CHECKIDENT 重新設置為使用 0 存在問題,如果這是在數據庫上隨後執行相同腳本,則重新設置為 1(所需的結果)。

腳本開頭的相關程式碼

-- disable all constraints
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

-- delete data in *ALL* tables (not just refTables)
EXEC sp_MSForEachTable "DELETE FROM ?"
-- reseed the indexes so primary keys start over at 1
declare @cmd varchar(4000)
declare cmds cursor for 
select 'DBCC CHECKIDENT(''' + t.name + ''', RESEED, 0);'
FROM sys.tables AS t
INNER JOIN sys.identity_columns AS i
ON t.object_id = i.object_id

open cmds
while 1=1
begin
   fetch cmds into @cmd
   if @@fetch_status != 0 break
   exec(@cmd)
end
close cmds;
deallocate cmds

我怎樣才能讓它在初始和後續執行中表現一致,這樣我就不會因為第 1 行變成第 0 行而破壞外鍵?

-- disable all constraints
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

-- delete data in *ALL* tables (not just refTables)
EXEC sp_MSForEachTable "DELETE FROM ?"
-- reseed the indexes so primary keys start over at 1
declare @cmd varchar(4000)
declare cmds cursor for 
select 'DBCC CHECKIDENT(''' + t.name + ''', RESEED, 0);'
FROM sys.tables AS t
INNER JOIN sys.identity_columns AS i
ON t.object_id = i.object_id
WHERE last_value IS NOT NULL

open cmds
while 1=1
begin
   fetch cmds into @cmd
   if @@fetch_status != 0 break
   exec(@cmd)
end
close cmds;
deallocate cmds

正如 Aaron Bertrand 連結的問題中的第二個答案所建議的那樣,添加 WHERE last_value IS NOT NULL 也解決了這個問題。

引用自:https://dba.stackexchange.com/questions/128645