如何在使用identity_insert后自动重新设定?

时间:2010-05-27 18:35:42

标签: sql-server identity identity-insert

我最近从PostgreSQL数据库迁移到SQL Server数据库。要切换数据我必须启用IDENTITY_INSERT。好吧,在任何表中执行插入操作时,我会发现由于重复的标识值(设置为主键)而导致各种奇怪的错误。

我有很多桌子。什么是自动重新设定每个表的标识以使其在max(RID)之后的最简单方法?

5 个答案:

答案 0 :(得分:27)

this link中的信息与SQL函数结合使用,该函数从您需要重置的每个表中获取最大值(RID)。例如,如果要在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函数已经有一段时间了:)

编辑:

感谢catch,将INTEGER更改为INT

USE YourDBName
GO 
SELECT *
FROM sys.Tables
GO 

这将为您提供数据库中所有用户表的列表。使用此查询作为“循环”,并允许重置所有表上的种子。

答案 1 :(得分:15)

汤米的回答是正确的,但如果我正在阅读documentation,那么这可以简化为:

DBCC CHECKIDENT ('myTable')

根据文件:

  

如果表的当前标识值小于最大值   身份值存储在标识列中,使用重置它   标识列中的最大值。

这使您无需手动查找最大ID,并且从SQL Server 2005开始支持。

这应该适用于原始OP案例。然而,文档提到了两种不起作用的情况,并且你必须手动查看最大ID值才能回到Tommy的解决方案:

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

答案 2 :(得分:1)

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

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

  

如果表的当前标识值小于最大值   身份值存储在标识列中,使用重置它   标识列中的最大值。

答案 3 :(得分:0)

回滚案例 -

我在我的数据库中进行测试,只有在我之前使用此处列出的代码时才有效(对+1进行修改 - 我们不需要这样做)。

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

注意,如果你在'ISNULL'部分之后加上+1,那么下一个标识列将跳转+1,例如 - 当前列10,代码之后的下一个将是11,如果你在isnull之后使用+1 ,将是+12。

AND,代码:

DBCC CHECKIDENT (teste_sequencial)

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

在案例回滚案件中,根本不适用于我。如果您打开一个事务并执行回滚,则重新设定将从事务中使用的最后一个数字开始。

答案 4 :(得分:0)

添加到@010110110101 的答案 - 跳过没有标识列的表:

-- sets all the seeds to 1
exec sp_MSforeachtable @command1 = 'IF OBJECTPROPERTY(object_id(''?''), ''TableHasIdentity'') = 1 DBCC CHECKIDENT (''?'', RESEED, 1)'

-- run it again to get MSSQL to figure out the MAX/NEXT seed automatically
exec sp_MSforeachtable @command1 = 'IF OBJECTPROPERTY(object_id(''?''), ''TableHasIdentity'') = 1 DBCC CHECKIDENT (''?'')'