Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server 2005 ROW_NUMBER() ohne ORDER BY

Sie können die Angabe einer expliziten Reihenfolge wie folgt vermeiden:

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

Bitte beachten Sie jedoch, dass dies nur eine Möglichkeit ist, die Angabe einer Reihenfolge zu vermeiden, und KEINE Garantie darstellt dass jede ursprüngliche Datenreihenfolge erhalten bleibt. Es gibt andere Faktoren, die dazu führen können, dass das Ergebnis geordnet wird, wie z. B. ein ORDER BY in der äußeren Abfrage. Um dies vollständig zu verstehen, muss man erkennen, dass das Konzept „nicht geordnet (auf eine bestimmte Weise)“ nicht dasselbe ist wie „die ursprüngliche Ordnung beibehalten“ (die auf eine bestimmte Weise geordnet IST!). Ich glaube, dass aus einer rein relationalen Datenbankperspektive das letztere Konzept nicht existiert , per Definition (obwohl es möglicherweise Datenbankimplementierungen gibt, die dagegen verstoßen, gehört SQL Server nicht dazu).

Der Grund für die Sperrhinweise besteht darin, den Fall zu verhindern, dass ein anderer Prozess mit dem Wert, den Sie verwenden möchten, zwischen den Teilen der Abfrageausführung Einfügungen durchführt.

Hinweis:Viele Leute verwenden (SELECT NULL) um die Einschränkung "keine Konstanten in der ORDER BY-Klausel einer Fensterfunktion erlaubt" zu umgehen. Aus irgendeinem Grund bevorzuge ich 1 über NULL .

Außerdem:Ich denke, eine Identitätsspalte ist weitaus besser und sollte stattdessen verwendet werden. Es ist nicht gut für die Parallelität, ganze Tabellen exklusiv zu sperren. Untertreibung.