Anda dapat menghindari menentukan urutan eksplisit sebagai berikut:
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};
Namun, harap perhatikan bahwa ini hanyalah cara untuk menghindari menentukan pemesanan dan TIDAK menjamin bahwa setiap pemesanan data asli akan dipertahankan. Ada faktor lain yang dapat menyebabkan hasil yang dipesan, seperti ORDER BY
dalam kueri luar. Untuk memahami sepenuhnya hal ini, kita harus menyadari bahwa konsep "tidak teratur (dengan cara tertentu)" tidak sama dengan "mempertahankan keteraturan asli" (yang ADALAH dipesan dengan cara tertentu!). Saya percaya bahwa dari perspektif basis data relasional murni, konsep terakhir tidak ada , menurut definisi (meskipun mungkin ada implementasi database yang melanggar ini, SQL Server bukan salah satunya).
Alasan petunjuk kunci adalah untuk mencegah kasus di mana beberapa proses lain menyisipkan menggunakan nilai yang Anda rencanakan untuk digunakan, di antara bagian-bagian dari eksekusi kueri.
Catatan:Banyak orang menggunakan (SELECT NULL)
untuk menyiasati pembatasan "tidak ada konstanta yang diizinkan dalam klausa ORDER BY dari fungsi windowing". Untuk beberapa alasan, saya lebih suka 1
lebih dari NULL
.
Juga:Saya pikir kolom identitas jauh lebih unggul dan harus digunakan sebagai gantinya. Tidak baik bagi konkurensi untuk mengunci seluruh tabel secara eksklusif. Meremehkan.