Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

SQL Server 2005 ROW_NUMBER() senza ORDER BY

Puoi evitare di specificare un ordine esplicito come segue:

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};

Tuttavia, tieni presente che è semplicemente un modo per evitare di specificare un ordine e NON garantisce che eventuali ordini di dati originali saranno conservati. Ci sono altri fattori che possono causare l'ordine del risultato, come un ORDER BY nella query esterna. Per comprendere appieno questo, bisogna rendersi conto che il concetto "non ordinato (in un modo particolare)" non è lo stesso di "mantenere l'ordine originale" (che è ordinato in un modo particolare!). Credo che da una pura prospettiva di database relazionale, quest'ultimo concetto non esista , per definizione (sebbene potrebbero esserci implementazioni di database che violano questo, SQL Server non è uno di questi).

Il motivo per i suggerimenti di blocco è impedire il caso in cui qualche altro processo venga inserito utilizzando il valore che prevedi di utilizzare, tra le parti della query in esecuzione.

Nota:molte persone usano (SELECT NULL) per aggirare la restrizione "nessuna costante consentita nella clausola ORDER BY di una funzione di windowing". Per qualche motivo, preferisco 1 su NULL .

Inoltre:penso che una colonna di identità sia di gran lunga superiore e dovrebbe essere utilizzata al suo posto. Non va bene per la concorrenza bloccare esclusivamente intere tabelle. Eufemismo.