237 votes

Comment pour exécuter une procédure stockée une fois pour chaque ligne renvoyée par la requête ?

J’ai une procédure stockée qui modifie les données de l’utilisateur d’une certaine manière. J’ai passer user_id et pour cela, c’est chose. Je veux exécuter une requête sur une table et ensuite pour chaque user_id j’ai trouver exécuter la procédure stockée une fois sur ce user_id

Comment écrirait une requête pour cela ?

SQL SERVER

282voto

Steven A. Lowe Points 40596

utiliser un curseur

ADDENDUM: [MS SQL curseur exemple]

declare @field1 int
declare @field2 int
declare cur CURSOR LOCAL for
    select field1, field2 from sometable where someotherfield is null

open cur

fetch next from cur into @field1, @field2

while @@FETCH_STATUS = 0 BEGIN

    --execute your sproc on each row
    exec uspYourSproc @field1, @field2

    fetch next from cur into @field1, @field2
END

close cur
deallocate cur

dans MS SQL, voici un exemple d'article

notez que les curseurs sont plus lents que les opérations à base d'ensemble, mais plus rapide que manuel tout-boucles; plus de détails dans cette SORTE de question

ADDENDUM 2: si vous allez traiter plus que juste un peu d'enregistrements, de les attirer dans une table temporaire première et exécuter le curseur au-dessus de la table temporaire; cela permettra d'éviter SQL à partir de l'escalade dans la table des serrures et de la vitesse de fonctionnement

L'ADDITIF 3: et bien sûr, si vous pouvez inline quel que soit votre procédure stockée pour chaque ID d'utilisateur et exécuter l'ensemble comme une seule instruction SQL update, qui serait optimal

58voto

KM. Points 51800

essayez de changer votre méthode si vous avez besoin de boucle!

au sein de la parent d'une procédure stockée, créer un #temp table qui contient les données que vous devez traiter. Appelez l'enfant de la procédure stockée, le n ° de la table temporaire sera visible et vous pouvez les traiter, nous l'espérons travailler avec l'ensemble des données et sans curseur ou en boucle.

cela dépend vraiment de ce que cet enfant de la procédure stockée est en train de faire. Si vous êtes à la mise à jour, vous pouvez "mettre à jour à partir de" se joindre à la table #temp et faire tout le travail en une seule instruction sans boucle. La même chose peut être faite pour l'insertion et la suppression. Si vous avez besoin de faire plusieurs mises à jour avec IFs, vous pouvez convertir plusieurs "mise à jour" avec le n ° de la table temporaire et de CAS d'utilisation des déclarations ou LORSQUE les conditions.

lorsque vous travaillez dans une base de données essayer de loos la mentalité de bouclage, c'est une véritable performance de vidange, seront la cause de verrouillage/bloquer et ralentir le traitement. Si vous en boucle partout, votre système ne sera pas l'échelle très bien, et il sera très dur pour accélérer lorsque l'utilisateur commence à se plaindre sur la lenteur de actualise.

poste le contenu de cette procédure que vous souhaitez appeler dans une boucle, et je parie que 9 fois sur 10, vous pouvez l'écrire à travailler sur un ensemble de lignes.

12voto

u07ch Points 5303

Quelque chose comme cette substitution sera nécessaire pour vos tables et vos noms de domaine.

7voto

Gary.Ray Points 4042

Il est préférable si vous pouvez éviter cela. La plupart de bases de données sont optimisées pour actions base set, et une boucle à l’aide d’un curseur sera relativement lente.

Cela étant dit, voici un bon exemple pour savoir comment faire cela à l’aide de SQL Server

6voto

randomsequence Points 398

Cela ne peut pas être fait avec une fonction définie par l'utilisateur pour répliquer quelque soit votre procédure stockée est en train de faire?

SELECT udfMyFunction(user_id), someOtherField, etc FROM MyTable WHERE WhateverCondition

où udfMyFunction est une fonction que vous faites qui prend l'ID de l'utilisateur et fait tout ce que vous devez faire avec elle.

Voir http://www.sqlteam.com/article/user-defined-functions pour un peu plus d'arrière-plan

Je suis d'accord que les curseurs vraiment devrait être évitée autant que possible. Et généralement c'est possible!

(bien sûr, ma réponse suppose que vous êtes seulement intéressés par l'obtention de la sortie de la SP et que vous ne modifiez pas les données réelles. Je trouve "modifie les données de l'utilisateur, d'une certaine manière un peu ambiguë de la question d'origine, donc j'ai pensé l'offrir cela comme une solution possible. Totalement dépend de ce que vous faites!)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X