7

我阅读的所有关于重新播种的文档都暗示了以下内容:

  1. SET @maxIdentityValue = (SELECT MAX(id) FROM tablename)
  2. 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'; 
4

3 回答 3

9

正如MSDN中所述,仅使用以下内容就足够了:

 DBCC CHECKIDENT('tablename', RESEED)  

大多数时候,但是有以下两种情况它不起作用:

  • 当前标识值大于表中的最大值。
  • 从表中删除所有行。

您必须按照您提到的方式进行操作(选择 max(id) 和其余部分),那么为什么要首先打扰呢?:)

于 2013-01-21T19:01:49.453 回答
2

在某些情况下,您可能需要确定最大值,以便重新播种并留出间隙(例如 max + 100)。一种情况可能是当您有一个表的多个副本并且您要从它们分发独立但互斥的身份范围时。

但是,我仍然不确定没有参数的 RESEED 在所有情况下都能正常工作。

您将表重新设置为最大值是否很常见?为什么?编码不佳的应用程序会在循环中生成一堆行,最终会回滚?

在任何情况下,您都希望将 MAX 和 RESEED 包装在事务中,以防止用户在您获取最大值之后但在您发出重新种子之前插入新行的机会。

于 2013-01-21T18:51:46.443 回答
2

(我正在从另一个 SO 页面重新发布我的答案)

也许最简单的方法(就像这听起来很疯狂,而且看起来很臭)就是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 (''?'')'

这只是利用文档中的评论的一种创造性方式:

如果表的当前标识值小于标识列中存储的最大标识值,则使用标识列中的最大值对其进行重置。

于 2016-11-03T04:55:34.527 回答