2009-03-18 2 views
0

Ich habe den folgenden TSQL-Codes:Dynamischer Cursor in einem Block in TSQL verwendet?

-- 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 
.... 

Ich benutze den Namen Wert nur in einem Loop-Block. Hier muss ich 1) eine Cursorvariable definieren, 2) öffnen, 3) zweimal holen und 4) schließen. In PL/SQL kann die Schleife wie folgt aussehen:

Es ist viel einfacher als meine TSQL-Codes. Keine Notwendigkeit, einen Cursor zu definieren. Es wird dynamisch erstellt, auf das innerhalb eines Schleifenblocks zugegriffen werden kann (ähnlich wie bei C# for loop). Nicht sicher, ob es in TSQL etwas Ähnliches gibt?

+0

Ich benutze Microsoft SQL Server 2005 –

Antwort

1

Cursor sind in SQL Server böse, wie sie wirklich die Leistung beeinträchtigen können - mein bevorzugter Ansatz ist eine Tabelle Variable (> = SQL Server 2005) mit einer automatischen inc ID-Spalte zu verwenden:

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 

Es sieht ziemlich langatmig arbeitet jedoch in jeder Situation und sollte weit leichter als ein Cursor

+0

Ich mag dieses. Ich verstehe jedoch nicht, warum in der Tabelle column2 datetime steht. Ohne die Säule funktioniert es gut. –

+0

OK. Ich sehe, dass Sie StartDate aus der Mitarbeitertabelle auswählen. Das tut mir leid. –

+0

Entschuldigung - die 2 Spalten waren nur Beispiele, um zu zeigen, dass Sie diese Spalte beliebig erweitern können, um sie als manh Spalten in der Tabellenvariablen zu verwenden – Macros

2

Etwas in diese Richtung könnte für Sie arbeitet, obwohl es

eine ID-Spalte auf, die oder eine andere eindeutige Kennung hängt
 
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

es funktioniert für mich. Vielen Dank! –

+0

tatsächlich, in einem Fall gibt es nur eine varchar-Spalte und Ihre Methode ist dort nicht anwendbar. –

+0

funktioniert auch auf Zeichen :) WÄHLEN SIE FALL WENN 'C'> 'B' DANN 1 ELSE 0 ENDE –

0

Da Sie aus einem Oracle-Hintergrund kommen, wo Cursor häufig verwendet werden, können Sie nicht Beachten Sie, dass Cursor in SQl Server Performance-Killer sind. Abhängig von dem, was Sie tatsächlich tun (sicherlich nicht nur die Variable drucken), kann es eine viel schnellere Set-basierte Lösung geben.

0

in einigen Fällen seine auch möglich, Trick wie diese sein:

DECLARE @name VARCHAR(MAX) 

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

PRINT @name 

Für eine Liste von Mitarbeiternamen.

Es kann auch machen durch Komma getrennte Zeichenfolge verwendet werden, ersetzen Sie einfach + CHAR (13) + CHAR (10) mit + ''

0

Warum nicht einfach nur zurück, das Recordset ein mit Wählen Sie die Anweisung aus. Ich nehme an, das Objekt besteht darin, die Werte in der Benutzeroberfläche zu kopieren und einzufügen (basierend auf der Tatsache, dass Sie einfach die Ausgabe drucken)? In Management Studio können Sie kopieren und aus dem Raster einfügen, oder drücken Sie + T und führen Sie dann die Abfrage und geben Sie die Ergebnisse als Teil der Nachrichten Registerkarte im Nur-Text-Format.

Wenn Sie dies über eine Anwendung ausführen, kann die Anwendung nicht auf die gedruckten Anweisungen zugreifen, da sie nicht innerhalb eines Recordsets zurückgegeben werden.