2009-03-18 4 views
0

私は、次のTSQLコードを持っている: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 
.... 

私はループブロック内の名前値を使用します。ここで私は1)カーソル変数を定義し、2)それを開き、3)2回フェッチし、4)それを閉じなければなりません。 PL/SQLでは、ループは次のようになります。

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

これは私のTSQLコードよりもずっと簡単です。カーソルを定義する必要はありません。ループブロック内でアクセス可能な動的に作成されます(C#forループのように)。 TSQLにこれと似たようなものがあるのか​​どうか分かりませんか?それはあなたがカーソルが頻繁に使用されているOracleのバックグラウンドから来ているので、あなたがないかもしれID列または他のいくつかのユニークな識別子

 
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

私はMicrosoft SQL Server 2005を使用しています –

答えて

1

カーソルは、SQL Serverの悪されている - 私の好まれるアプローチは、オート株式会社のID列を持つテーブル変数(> = SQL Server 2005の)を使用することです:

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 

それはきれいに見えます長いったらしいは、しかしどのような状況で動作し、カーソルよりも、いくつかのケースでは

+0

私はこの1つが好きです。しかし、なぜ私はテーブルにcolumn2 datetimeがあるのか​​分からない。列がなければ、正常に動作します。 –

+0

OK。私はあなたが従業員のテーブルからStartDateを選択するのを見る。そのために残念。 –

+0

申し訳ありません - 2列は、テーブル変数で好きなようにこれを拡張してmanh列として使用できることを示すための単なる例でした – Macros

2

何かが、あなたのために働くかもしれませんSQl Serverのカーソルはパフォーマンスを低下させることに注意してください。実際に何をしているのか(確かに変数を印刷するだけではない)には、はるかに高速なセットベースのソリューションがあるかもしれません。彼らは本当にパフォーマンスが低下する可能性として

+0

それは私のために働く。ありがとう! –

+0

実際には、1つの場合にはvarchar列が1つしかなく、その方法はそこには適用されません。 –

+0

も文字で動作します:) SELECT CASE 'C'> 'B' THEN 1 ELSE 0 END –

0

を持つにも依存するが、これらの線に沿って

0

、そのこともでき、この1のようなトリックを使用するには、はるかに軽量でなければなりません:

DECLARE @name VARCHAR(MAX) 

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

PRINT @name 

従業員名のリストについては、また、ちょうど+と+ CHAR(10)+ CHAR(13)を交換、カンマ区切りの文字列を作るために使用することができます

''

0

はなぜ単純に使用してレコードセットを返しませんselectステートメント。私は、あなたが単純に出力を印刷しているという事実に基づいて、UIの値をコピー&ペーストすることを目的としていますか? Managementスタジオでは、グリッドからコピー&ペーストするか、+ Tキーを押してクエリを実行し、結果をプレーンテキストのメッセージタブの一部として返すことができます。

これをアプリケーション経由で実行すると、アプリケーションはレコードセット内で返されないため、印刷されたステートメントにアクセスできなくなります。

関連する問題