在现有应用程序中,有一个User_Log表,其中包含一个顺序ID列。
[id] [int] IDENTITY(1,1) NOT NULL
但是,在检查表时,我发现该130万行表中缺少16,874个ID。
在此表中插入一行时,在什么时候分配了下一个ID值?
如果OnInsert触发器失败,ID是否增加但没有写入数据?
还有什么其他类型的错误可能导致不写行,但ID递增了?
此查询显示缺少的ID。
WITH Missing (miss_ID, maxid)
AS
(
SELECT 1 AS miss_ID, (select max(id) from user_log)
UNION ALL
SELECT miss_ID + 1, maxid FROM Missing
WHERE miss_ID < maxid
)
SELECT miss_ID
FROM Missing
LEFT OUTER JOIN user_log UL on UL.id = Missing.miss_ID
WHERE UL.id is NULL
OPTION (MAXRECURSION 0)
;
我正在尝试排除删除用户活动日志中的记录,这是一件坏事。
谢谢您的协助。
答案 0 :(得分:1)
在此表中插入一行时,什么时候分配了下一个ID值?
该值在插入之前生成。这是非事务性的,因为其他会话可以立即生成连续值,而无需等待插入是否最终成功并被提交。
如果OnInsert触发器失败,ID是否增加了,但没有写入任何数据?
是的
还有什么其他类型的错误可能导致不写行,但ID递增了?
任何在表中包含插入内容的事务失败或回滚将在IDENTITY值中留下空白。另外,SQL Server默认情况下还会缓存生成的标识值的块,并且SQL Server进程失败将留下空白,通常大约有1000个值。