这个问题已得到很好的描述,并解释了为什么会发生(即 StackOverflow 线程 1、2.3),但是实际可靠的解决方案呢?我有许多脚本,它们必须输出表(通过外部规范),行 ID 总是从 1 开始,而不管表状态(新的或只是删除行)。
问题如下 - 如果我运行:
DBCC CHECKIDENT ('TableName', RESEED, 0);
如前所述,根据 SQL Server 规范,此行为是正确的。为了避免这种情况,有人建议只运行:
DBCC CHECKIDENT ('TableName', RESEED);
新创建的表上的第一个身份将是 1(至少在我的环境设置中它有效),但是对于删除了数据被删除的表,它将保存last seed(可能是 123456)。
我也试过:
DBCC CHECKIDENT ('TableName', RESEED, 1);
第一个ID将是2。
那么 ALWAYS 为第一个插入的行获取 ID=1 的实用方法是什么?在附加的链接中,有人建议插入一个虚拟行并将其删除,然后使用“0”重新播种,最后开始插入行。这是正确的做法吗?
本质上,您有 2 个选择。
你可以按照你建议的方式在创建后插入虚拟数据然后删除它,在这种情况下
DBCC CHECKIDENT ('TableName', RESEED, 0);
将始终有效。
您也可以避免事先删除行并执行以下操作:
IF NOT EXISTS (SELECT 1 FROM TableName)
BEGIN
DBCC CHECKIDENT ('TableName', RESEED, 1);
END
ELSE
BEGIN
DELETE * FROM TableName;
DBCC CHECKIDENT ('TableName', RESEED, 0);
END
GO
删除记录后可以查看
@@ROWCOUNT
,查看记录是否被删除。
如果
@@ROWCOUNT
大于0那么你使用DBCC CHECKIDENT ('TableName', RESEED, 0);
否则使用DBCC CHECKIDENT ('TableName', RESEED, 1);
DECLARE @last_value INT;
SELECT @last_value = CONVERT(INT, last_value)
FROM sys.identity_columns
WHERE object_id = OBJECT_ID('${table}');
IF @last_value IS NOT NULL
BEGIN
-- If rows have been inserted to the table since it was created,
-- or all rows have been removed by using the DELETE statement,
DBCC CHECKIDENT ('${table}', RESEED, 0);
END
ELSE
BEGIN
-- If no rows have been inserted to the table since it was created,
-- or all rows have been removed by using the TRUNCATE TABLE statement,
DBCC CHECKIDENT ('${table}', RESEED, 1);
END