可避免指定明确排序如下:
INSERT dbo.TargetTable (ID, FIELD)
SELECT
Row_Number() OVER (ORDER BY (SELECT 1))
+ Coalesce(
(SELECT Max(ID) FROM dbo.TargetTable WITH (TABLOCKX, HOLDLOCK)),
0
),
FieldValue
FROM dbo.SourceTable
WHERE {somecondition};
但是,请注意,仅仅是为了避免指定排序和不保证任何原始数据顺序将被保留的方式。还有其他因素可能导致结果被排序,例如外部查询中的ORDER BY
。为了充分理解这一点,人们必须认识到,“不按照(以特定方式)排序”与“保留原始顺序”(以特定方式排列)不同。我认为从纯粹的关系数据库的角度来看,后一个概念不存在,的定义(虽然可能有数据库实现违反了这个,SQL Server不是其中之一)。
锁提示的原因是为了防止在查询执行的各个部分之间使用您计划使用的值插入其他一些进程。
注意:许多人使用(SELECT NULL)
来解决“窗口函数的ORDER BY子句中允许的不允许的常量”限制。由于某种原因,我比NULL
更喜欢1
。
另外:我认为身份专栏是非常优越的,应该用来代替。并发性并不擅长锁定整个表。轻描淡写。
什么是源表的聚集索引?我假设你说的“SourceTable的原始顺序”就是你说的吗?如果它是一堆,那么没有特定的顺序。 – 2011-01-26 22:38:50