TSQL – effectue le code pour chaque ligne d'un select

Est-il possible d'exécuter du code pour chaque ligne d'une sélection sans utiliser de slider?

Dans mon cas: j'ai une table temporaire pour stocker des données pour un script complexe. A la fin je veux piquer quelques informations de cette table (limitées par quelques conditions) à la sortie.

Actuellement, j'utilise un slider avec une sélection pour limiter les lignes de la table. Dans ce slider j'utilise

print '...' 

pour générer la sortie.

Il doit y avoir un moyen plus facile de faire de telles choses …

modifier:

 create table #tmpAtsortingbutes(AtsortingbuteId uniqueidentifier, Value float, ValueSsortingng nvarchar(max), ActionId uniqueidentifier) insert into #tmpAtsortingbutes (AtsortingbuteId, Value, ValueSsortingng, ActionId) select ID,..... -- in this select i'm doing some value conversions, if conversion is not possible i'm using -1 insert into ActionAtsortingbute (ActionDefinitionID, Discriminator, ID, ReferredActionID, ValueDate, ValueListID, ValueMoney, ValueSsortingng, ValueUserID) select @defId, 'ActionAtsortingbuteMoneyEntity', NEWID(), ActionId, null, null, Value, null, null from #tmpAtsortingbutes -- afterwards there is this cursor where I'm printint all rows where Value = -1 

L'exécution d'une instruction d'printing pour chaque ligne d'un set de résultats nécessite à peu près un slider ou une approche similaire à celle-ci

 declare @id int, @stuff varchar(20) declare @tmp table ( id int not null , stuff varchar(20) primary key(id) ) insert @tmp select id, stuff from mastertable where condition1 > condition2 select top 1 @id=id, @stuff=stuff from @tmp while (@@rowcount > 0) begin print @stuff delete from @tmp where id=@id select top 1 @id=id, @stuff=stuff from @tmp end 

Vous êtes toujours en boucle à travers chaque ligne, mais vous évitez un slider. Puisque vous utilisez une table var vous au lieu d'un slider vous évitez le locking de table, mais ce n'est pas nécessairement une meilleure approche. Vous pouvez traiter ligne par ligne de différentes manières, par exemple en ajoutant une "colonne traitée" ou en numérotant toutes les lignes sélectionnées 1..n et en répétant le nombre de lignes sélectionnées.

Vous ne pouvez éviter le traitement ligne par ligne que si vous pouvez effectuer une opération basée sur un set. Il n'y a pas assez d'informations dans votre question pour voir si cela est évitable dans TSQL

Maintenant, l'écriture d'un process CLR peut être plus flexible car vous disposez d'un model de programmation beaucoup plus riche, et il y a peu de frais généraux à parcourir chaque ligne du jeu de résultats dans le process CLR. Effectuer un appel de database à partir du process CLR pour chaque ligne qu'un appel de database de chaque ligne dans TSQL

EDIT – Je vois quelqu'un déjà ajouté un moyen possible de convertir vos instructions d'printing en une opération orientée set. c'est à dire

 declare @msg varchar(max) select @msg = '' select msg = @msg + stuff from mastertable where condition1 > condition2 print @msg 

C'est OK, en fait, ce à quoi je faisais reference quand j'ai dit d'effectuer une opération. Une opération basée sur un set est toujours préférée lorsque cela est possible. Cela peut ne pas être évident, mais la concaténation de strings peut également devenir très lente dans cet exemple aussi si de nombreuses lignes sont impliquées.


J'ai dit que l'utilisation d'un var temp évite le locking de la table. Ce n'est pas tout à fait vrai car le server SQL écrit les variables temporaires dans une table de tempdb. Ce que je voulais vraiment dire, c'est que vous évitez de verrouiller une table de production et que vous êtes le seul user de cette table, vous n'êtes pas en concurrency pour un access simultané.

Je n'ai également fait aucune tentative pour optimiser cela. Par exemple, la boucle interne pourrait suivre l'identifiant et la condition where devient où id> @id (vous voudrez également une key primaire définie sur id). Puisque la table temporaire n'est pas mise à jour pendant chaque itération de boucle, je m'attendrais à ce qu'elle soit plus rapide.

Je pense que vous devez fournir plus de détails, mais vous cherchez peut-être quelque chose comme:

 declare @msg varchar(max)=''; select @msg = @msg + 'Output line: ' + ColumnA + ' -- ' + 'ColumnB' + char(13)+char(10) from #temp where ... ; print @msg;