2009-03-18 7 views
0

J'ai les codes TSQL suivants:Curseur dynamique utilisé dans un bloc TSQL?

-- 1. define a cursor 
DECLARE c_Temp CURSOR FOR 
    SELECT name FROM employees; 

DECLARE @name varchar(100); 
-- 2. open it 
OPEN c_Temp; 
-- 3. first fetch 
FETCH NEXT FROM c_Temp INTO @name; 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    print @name; 
    FETCH NEXT FROM c_Temp INTO @name; -- fetch again in a loop 
END 
-- 4. close it 
.... 

J'utilise la valeur du nom que dans un bloc de boucle. Ici, je dois 1) définir une variable curseur, 2) l'ouvrir, 3) aller chercher deux fois et 4) le fermer. En PL/SQL, la boucle peut être comme ceci:

FOR rRec IN (SELECT name FROM employees) LOOP 
    DBMS_OUTPUT.put_line(rRec.name); 
END LOOP; 

C'est beaucoup plus simple que mes codes TSQL. Pas besoin de définir un curseur. Il est créé dynamiquement et accessible dans un bloc de boucle (un peu comme C# pour boucle). Vous ne savez pas s'il y a quelque chose de similaire dans TSQL?

+0

J'utilise Microsoft SQL Server 2005 –

Répondre

1

Curseurs sont mal dans Sql Server, car ils peuvent vraiment dégrader les performances - mon approche privilégiée est d'utiliser une variable de table (> = Sql Server 2005) avec une colonne inc auto ID:

Declare @LoopTable as table (
    ID int identity(1,1), 
    column1 varchar(10), 
    column2 datetime 
) 
insert into @LoopTable (column1, column2) 
select name, startdate from employees 

declare @count int 
declare @max int 
select @max = max(ID) from @LoopTable 
select @count = 1 

while @count <= @max 
begin 
    --do something here using row number '@count' from @looptable 
    set @count = @count + 1 
end 

Il semble assez verbeux fonctionne cependant dans toute situation et devrait être beaucoup plus léger qu'un curseur

+0

J'aime celui-ci. Cependant, je ne comprends pas pourquoi il y a column2 datetime dans la table. Sans la colonne, cela fonctionne bien. –

+0

OK. Je vois que vous sélectionnez StartDate dans la table des employés. Désolé. –

+0

Désolé - les 2 colonnes étaient juste des exemples pour montrer que vous pouvez étendre ceci pour utiliser comme colonnes manh que vous le souhaitez dans la variable table – Macros

2

Quelque chose le long de ces lignes pourrait fonctionner pour vous, bien que cela dépende d'avoir une colonne d'identité ou d'un autre identifiant unique

 
Declare @au_id Varchar(20) 
Select @au_id = Min(au_id) from authors 

While @au_id IS NOT NULL 
Begin 
      Select au_id, au_lname, au_fname from authors Where au_id = @au_id 
      Select @au_id = min(au_id) from authors where au_id > @au_id 
End 
+0

cela fonctionne pour moi. Merci! –

+0

en fait, dans un cas, il n'y a qu'une seule colonne varchar et votre méthode ne s'applique pas là. –

+0

fonctionne aussi sur les caractères :) CHOISIR LE CAS QUAND 'C'> 'B' ALORS 1 ELSE 0 FIN –

0

Puisque vous venez d'un arrière-plan Oracle où les curseurs sont fréquemment utilisés, vous ne pouvez pas Sachez que dans SQl Server, les curseurs sont des outils de gestion des performances. En fonction de ce que vous faites réellement (sûrement pas juste en imprimant la variable), il peut y avoir une solution beaucoup plus rapide basée sur un ensemble.

0

dans certains cas, c'est aussi possible d'utiliser truc comme celui-ci:

DECLARE @name VARCHAR(MAX) 

SELECT @name = ISNULL(@name + CHAR(13) + CHAR(10), '') + name 
FROM employees 

PRINT @name 

Pour une liste des noms des employés.

Il peut également être utilisé pour faire chaîne séparés par des virgules, il suffit de remplacer + CHAR (13) + CHAR (10) avec + ''

0

Pourquoi ne pas tout simplement retourner le jeu d'enregistrements à l'aide d'un sélectionnez l'instruction. Je suppose que l'objet est de copier et coller les valeurs dans l'interface utilisateur (basé sur le fait que vous imprimez simplement la sortie)? Dans Management Studio, vous pouvez copier et coller à partir de la grille ou appuyer sur + T, puis exécuter la requête et renvoyer les résultats dans l'onglet Messages en texte brut.

Si vous l'exécutez via une application, l'application ne pourra pas accéder aux instructions imprimées car elles ne sont pas renvoyées dans un jeu d'enregistrements.

Questions connexes