You can omit explicit ordering as follows:
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};
However, please note that this is just a way to avoid specifying an order, and DOES NOT guarantee that the original data order will be preserved. There are other factors that can lead to an ordering of the result, for example, ORDER BY in an external query. To fully understand this, you need to understand that the concept of "not ordered (in a certain way)" does not coincide with "maintaining the original order" (which is ordered in a certain way!). I believe that from the point of view of a pure relational database, the latter concept does not exist by definition (although there may be database implementations that violate this, SQL Server is not one of them).
The reason for the lock prompts is to prevent the case where some other process inserts use the value you plan to use between parts of the query being executed.
Note. Many people use (SELECT NULL) to get around "no constants allowed in the ORDER BY clause of a window constraint." For some reason, I prefer 1 over NULL .
Also: I think the identity column is much superior and should be used instead. This is not suitable for concurrency for exclusive locking of entire tables. Understatement.
ErikE Jan 27 '11 at 1:10 2011-01-27 01:10
source share