Du kan undgå at angive en eksplicit rækkefølge som følger:
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};
Bemærk dog, at det kun er en måde at undgå at specificere en ordre på og ikke garanterer at enhver original databestilling vil blive bevaret. Der er andre faktorer, der kan forårsage, at resultatet bliver bestilt, såsom en ORDER BY
i den ydre forespørgsel. For fuldt ud at forstå dette, må man indse, at begrebet "ikke ordnet (på en bestemt måde)" ikke er det samme som "at bevare original orden" (som ER ordnet på en bestemt måde!). Jeg mener, at fra et rent relationsdatabaseperspektiv findes ikke det sidste begreb , per definition (selvom der kan være databaseimplementeringer, der overtræder dette, er SQL Server ikke en af dem).
Årsagen til låsetipsene er at forhindre tilfældet, hvor en anden proces indsætter ved hjælp af den værdi, du planlægger at bruge, mellem de dele af forespørgslen, der udføres.
Bemærk:Mange bruger (SELECT NULL)
for at komme uden om begrænsningen "ingen konstanter tilladt i ORDER BY-sætningen af en vinduesfunktion". Af en eller anden grund foretrækker jeg 1
over NULL
.
Desuden:Jeg synes, en identitetsspalte er langt overlegen og bør bruges i stedet for. Det er ikke godt for samtidighed udelukkende at låse hele borde. Underdrivelse.