可避免指定明確排序如下:
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