Vous pouvez éviter de spécifier un ordre explicite comme suit :
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};
Cependant, veuillez noter qu'il s'agit simplement d'un moyen d'éviter de spécifier une commande et ne garantit PAS que tout ordre de données d'origine sera conservé. Il existe d'autres facteurs qui peuvent entraîner l'ordre du résultat, comme un ORDER BY
dans la requête externe. Pour bien comprendre cela, il faut se rendre compte que le concept "non ordonné (d'une manière particulière)" n'est pas la même chose que "conserver l'ordre d'origine" (qui EST ordonné d'une manière particulière !). Je crois que du point de vue de la base de données relationnelle pure, ce dernier concept n'existe pas , par définition (bien qu'il puisse y avoir des implémentations de bases de données qui enfreignent cela, SQL Server n'en fait pas partie).
La raison des indications de verrouillage est d'empêcher le cas où un autre processus s'insère en utilisant la valeur que vous prévoyez d'utiliser, entre les parties de la requête en cours d'exécution.
Remarque :De nombreuses personnes utilisent (SELECT NULL)
pour contourner la restriction "aucune constante autorisée dans la clause ORDER BY d'une fonction de fenêtrage". Pour une raison quelconque, je préfère 1
sur NULL
.
Aussi:je pense qu'une colonne d'identité est de loin supérieure et devrait être utilisée à la place. Il n'est pas bon pour la simultanéité de verrouiller exclusivement des tables entières. Euphémisme.