次のように明示的な順序を指定することは避けられます:
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はそれらの1つではありません)。
ロックヒントの理由は、実行するクエリの部分の間に、使用する予定の値を使用して他のプロセスが挿入するケースを防ぐためです。
注:多くの人が(SELECT NULL)
を使用しています 「ウィンドウ関数のORDERBY句で許可されている定数はありません」という制限を回避するため。どういうわけか、私は1
を好みます NULL
以上 。
また、ID列ははるかに優れているため、代わりに使用する必要があると思います。テーブル全体を排他的にロックすることは、同時実行には適していません。控えめな表現。