Je souhaite mettre à jour les lignes d'une table dans un ordre spécifique, comme on pourrait s'y attendre en incluant une clause ORDER BY, mais SQL Server ne prend pas en charge la clause ORDER BY dans les requêtes UPDATE.SQL Server 2005: mettre à jour les lignes dans un ordre spécifié (comme ORDER BY)?
J'ai vérifié this question qui a fourni une bonne solution, mais ma requête est un peu plus compliquée que celle spécifiée ici.
UPDATE TableA AS Parent
SET Parent.ColA = Parent.ColA + (SELECT TOP 1 Child.ColA
FROM TableA AS Child
WHERE Child.ParentColB = Parent.ColB
ORDER BY Child.Priority)
ORDER BY Parent.Depth DESC;
Alors, ce que j'espère que vous remarquerez est qu'une seule table (TableA
) contient une hiérarchie de lignes, dans laquelle une ligne peut être le parent ou l'enfant d'une autre rangée. Les lignes doivent être mises à jour dans l'ordre de l'enfant le plus profond jusqu'au parent racine. C'est parce que TableA.ColA
doit contenir une concaténation à jour de sa propre valeur actuelle avec les valeurs de ses enfants (je réalise que cette requête ne concerne qu'un seul enfant, mais c'est pour des raisons de simplicité - le but de l'exemple dans cette question ne nécessite pas plus de verbosité), la requête doit donc être mise à jour de bas en haut.
La solution proposée dans la question je l'ai mentionné ci-dessus est la suivante:
UPDATE messages
SET status=10
WHERE ID in (SELECT TOP (10) Id
FROM Table
WHERE status=0
ORDER BY priority DESC
);
La raison pour laquelle je ne pense pas que je peux utiliser cette solution est parce que je suis le référencement des valeurs de colonne de la table parent dans ma sous-requête (voir WHERE Child.ParentColB = Parent.ColB
), et je ne pense pas que deux sous-requêtes de frères auraient accès aux données des autres. Jusqu'à présent, j'ai seulement déterminé une façon de fusionner cette solution avec mon problème actuel, et je ne pense pas que cela fonctionne.
UPDATE TableA AS Parent
SET Parent.ColA = Parent.ColA + (SELECT TOP 1 Child.ColA
FROM TableA AS Child
WHERE Child.ParentColB = Parent.ColB
ORDER BY Child.Priority)
WHERE Parent.Id IN (SELECT Id
FROM TableA
ORDER BY Parent.Depth DESC);
La sous-requête WHERE..IN
ne reviendra pas en fait un sous-ensemble des lignes, il suffit de retourner la liste complète des ID dans l'ordre que je veux. Cependant (je ne sais pas avec certitude - s'il vous plaît dites-moi si je me trompe) je pense que la clause WHERE..IN
ne se souciera pas de l'ordre des ID entre parenthèses - il va juste vérifier l'ID de la ligne qu'il veut actuellement mettre à jour pour voir si c'est dans cette liste (qui, ils le sont tous) dans l'ordre qu'il essaie déjà de mettre à jour ... Ce qui serait juste un gaspillage total de cycles, car cela ne changerait rien. Donc, en conclusion, j'ai regardé autour et ne peux pas sembler trouver un moyen de mettre à jour dans un ordre spécifié (et inclus le raison je dois mettre à jour dans cet ordre, parce que je suis sûr que je le ferais sinon, obtenez les réponses «pourquoi?» si utiles) et je suis en train de cliquer sur Stack Overflow pour voir si certains de vos gourous qui en savent plus sur SQL que moi (ce qui ne dit pas grand-chose) connaissent un moyen efficace de le faire. Il est particulièrement important que je n'utilise qu'une seule requête pour terminer cette action.
Une longue question, mais je voulais couvrir mes bases et vous donner autant d'informations que possible. :)
Des pensées? Les instructions UPDATE seront exécutées comme une seule requête, pas comme un résultat étape par étape.
Oui, les curseurs sont exactement ce que je cherche à éviter avec cela. :) Merci, je vais jeter un oeil aux expressions CTE. – JMTyler