Вы можете избежать указания явного порядка следующим образом:
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 оконной функции". По какой-то причине я предпочитаю 1
над NULL
.
Также: я думаю, что столбец идентификаторов намного лучше и должен использоваться вместо него. Для параллелизма не рекомендуется блокировать только целые таблицы. Занижение.