换句话说,以下“光标”方法是否有效:
LastMax
"SELECT * FROM MyTable WHERE Id > {0}", LastMax
为了使其正常工作,我必须确保我在步骤1中未获得的每行的ID大于LastMax
。这是保证,还是我可以遇到奇怪的竞争条件?
答案 0 :(得分:17)
保证绝对在任何情况下都不可能获得可能小于或等于当前最大值的值?不,没有这样的保证。也就是说,这种情况可能发生的情况是有限的:
假设没有这些情况,您就可以避免竞争条件造成下一个值低于现有值的情况。也就是说,不能保证行按照其身份值的顺序提交。例如:
在第一个交易提交之前,43存在但42则不存在。标识列只是保留一个值,它不是指示提交的顺序。
答案 1 :(得分:4)
我认为这可能会出错,具体取决于交易的持续时间 考虑以下事件序列:
您的代码永远不会找到事务A插入的行。执行第6步时尚未提交。当执行下一个查询时,将无法找到它,因为它在标识列中的值低于查询所查找的值。
如果您使用read-uncommitted隔离模式
执行查询,则可能会有效答案 2 :(得分:2)
身份将始终遵循定义身份的增量:
IDENTITY [(种子,增量)] http://msdn.microsoft.com/en-us/library/aa933196(SQL.80).aspx
可以是正面的也可以是负面的(你可以让它向前或向后递增)。如果您将身份设置为向前递增,则您的身份值将始终大于之前的值,但如果您回滚INSERT,则可能会遗漏一些。
是的,如果您将身份增量设置为正值,则循环逻辑将起作用。
答案 3 :(得分:1)
如果有人打开身份插入并手动将记录插入到跳过的ID(或者在某些情况下为负数),则唯一可能插入的记录可能会被插入。这是一种相当罕见的情况,通常只能由系统管理员完成。例如,可能会重新插入意外删除的记录。
答案 4 :(得分:0)
SQL Server唯一保证的是您的IDENTITY列将始终递增。
要考虑的事情:
这解释了为什么SQL Server不保证顺序INDENTITY。
有一种方法可以使用DBCC命令重置IDENTITY列。但在此之前,请考虑以下事项:
IDENTITY列是DBRM中永远不会更改的最重要元素之一。
以下是一个可以帮助您的链接:Understanding IDENTITY columns
编辑:您似乎要做的事情应该起作用,因为LastMax的IDENTITY列将始终为每个INSERTed行递增。所以:
- 从数据表中选择行;
- 保存LastMax状态;
- 选择Id>行LastMax。
醇>3)只会选择IDENTITY列大于LastMax的行,因此在保存LastMax后插入。