Você pode evitar especificar uma ordenação explícita da seguinte forma:
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};
No entanto, observe que é apenas uma maneira de evitar especificar um pedido e NÃO garante que qualquer ordenação de dados original será preservada. Existem outros fatores que podem fazer com que o resultado seja ordenado, como um
ORDER BY
na consulta externa. Para entender isso completamente, é preciso perceber que o conceito "não ordenado (de uma maneira particular)" não é o mesmo que "manter a ordem original" (que É ordenada de uma maneira particular!). Acredito que de uma perspectiva de banco de dados relacional puro, o último conceito não existe , por definição (embora possa haver implementações de banco de dados que violem isso, o SQL Server não é uma delas). O motivo das dicas de bloqueio é evitar o caso em que algum outro processo é inserido usando o valor que você planeja usar, entre as partes da execução da consulta.
Nota:Muitas pessoas usam
(SELECT NULL)
para contornar a restrição "nenhuma constante permitida na cláusula ORDER BY de uma função de janela". Por algum motivo, prefiro 1
sobre NULL
. Além disso:acho que uma coluna de identidade é muito superior e deve ser usada. Não é bom que a simultaneidade bloqueie exclusivamente tabelas inteiras. Eufemismo.