我有一个带有标识集的SQL表:
CREATE TABLE MyTable(
MyTableID int IDENTITY(1,1) NOT NULL,
RecordName nvarchar(100) NULL)
这张桌子发生了什么事,导致行为异常。我需要找出什么。
插入时:
INSERT MyTable(RecordName)
VALUES('Test Bug')
SELECT SCOPE_IDENTITY() -- returns 0
SELECT * FROM MyTable -- displays: 0, 'Test Bug'
这是一个问题,因为此插入内容上方的代码期望第一个ID为1
-我无法弄清楚IDENTITY(1,1)
最终的结果是0
。
如果(在执行之前INSERT
)我检查了身份,则返回null:
DBCC CHECKIDENT (MyTable, NORESEED)
检查身份信息:当前身份值'NULL',当前列值'NULL'。
我知道几种解决此问题的方法;我首先需要知道表格如何进入此状态?
我知道CHECKIDENT
返回null的唯一方法是表是否刚刚创建,但是IDENTITY(1,1)
很荣幸能得到,INSERT
原因SCOPE_IDENTITY()
是1
。
或者,0
如果我强制-1
使用当前种子(DBCC CHECKIDENT (MyTable, RESEED, -1)
或使用SET IDENTITY_INSERT MyTable ON
),则可以获取下一个ID ,但是随后检查报告该当前-1
种子(而不是null),所以这不可能发生。
数据库如何进入列具有的状态IDENTITY(1,1)
,DBCC CHECKIDENT (MyTable, NORESEED)
返回null,但下一个INSERT
原因SCOPE_IDENTITY()
是0
?
我希望有人/某事已经发生:
DBCC CHECKIDENT ('dbo.MyTable', RESEED, 0);
如果运行以下命令:
CREATE TABLE dbo.MyTable(
MyTableID int IDENTITY(1,1) NOT NULL,
RecordName nvarchar(100) NULL
);
DBCC CHECKIDENT ('dbo.MyTable', RESEED, 0);
DBCC CHECKIDENT ('dbo.MyTable', NORESEED);
第二个CHECKIDENT
仍然返回NULL
:
检查身份信息:当前身份值'NULL',当前列值'NULL'。
但是,下一个标识值将为0。这是记录的行为,MSDN指出:
当前身份值设置为new_reseed_value。如果自创建以来没有将任何行插入到表中,则在执行DBCC CHECKIDENT之后插入的第一行将使用new_reseed_value作为标识。否则,插入的下一行将使用new_reseed_value +1。如果new_reseed_value的值小于标识列中的最大值,则对该表的后续引用将生成错误消息2627。
这仅适用于其中的last_value
列sys.identity_columns
仍为NULL的新创建/截断的表。如上所述,如果要插入一行,将其删除,然后重新设置为0,则新标识仍为1。
完整的测试脚本
IF OBJECT_ID(N'dbo.T', 'U') IS NOT NULL
DROP TABLE dbo.T;
CREATE TABLE dbo.T(ID INT IDENTITY(1,1) NOT NULL);
INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
-- OUTPUTS 1
DELETE dbo.T;
DBCC CHECKIDENT ('dbo.T', RESEED, 0);
INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
-- OUTPUTS 1
TRUNCATE TABLE dbo.T;
DBCC CHECKIDENT ('dbo.T', RESEED, 0);
INSERT dbo.T OUTPUT inserted.* DEFAULT VALUES;
-- OUTPUTS 0
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句