Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

SQL Server 2005 ROW_NUMBER() sem ORDER BY


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.