我读到的有关重新种植的所有文件都提出了以下内容:
SET @maxIdentityValue = (SELECT MAX(id) FROM tablename)
DBCC CHECKIDENT('tablename', RESEED, @maxIdentityValue)
然而在我看来,只需要一个简单的DBCC CHECKIDENT('tablename', RESEED)
,它将自动从表中确定正确的标识值,而不提供最大值。
首先使用MAX
首先提取值是否有理由(性能或其他原因)?
背驮式问题:我需要重新设置的原因是因为我每次运行数据库复制时都使用复制和身份设置为Null。我究竟做错了什么?如何为每个表维护正确的身份种子?
现在我没有使用最大值。这是我正在使用的存储过程(我使用sys.columns
上的查询生成它,然后将每个剪切并粘贴到一个新的查询窗口.Messier,更慢,更不优雅,但我不是很熟悉存储过程并且不想使用动态SQL查询):
declare @seedval integer
declare @maxval integer
declare @newval integer
set @seedval = (select ident_current('mytable'));
set @maxval = (select MAX(id) from mytable);
if @maxval > @seedval or @seedval is NULL
BEGIN
print 'Need to reseed: max is ' + cast(@maxval as varchar) + ' and seed is ' + cast(@seedval as varchar)
dbcc checkident('mytable', RESEED);
set @newval = (select ident_current('mytable'));
print 'Max is ' + cast(@maxval as varchar) + ' and seed is ' + cast(@newval as varchar)
END
ELSE
print 'No need to reseed';
答案 0 :(得分:8)
正如MSDN中所述,只使用以下是相当的:
DBCC CHECKIDENT('tablename', RESEED)
大部分时间,但有两个条件不起作用:
你必须按照你提到的方式去选择(选择max(id)和其他),所以为什么要先烦? :)
答案 1 :(得分:2)
在某些情况下,您可能需要确定最大值,以便重新设置并留下间隙(例如,最大值+ 100)。一种情况可能是您拥有表的多个副本,并且您将从中分发独立但相互排斥的标识范围。
但是,我仍然不相信没有参数的RESEED在所有情况下都能正常工作。
您是否经常将表重新播种到最大值?为什么?编码不良的应用程序会在循环中生成一堆行,最终会回滚?
在任何情况下,您都希望在事务中包装MAX和RESEED,以防止用户在您获取最大值之后但在您发出重新设定之前插入新行的可能性。
答案 2 :(得分:1)
(I'm reposting my answer from this other SO page)
也许最简单的方法(就像听起来一样疯狂,而且看起来像代码一样臭)只是像这样运行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 (''?'')'
这只是一种利用文档评论的创造性方法:
如果表的当前标识值小于最大值 身份值存储在标识列中,使用重置它 标识列中的最大值。