SQLServerのカーソル利用について

SQLServerとかでストアド使った処理でよくあるカーソル使った処理。

<よくあるカーソル利用時の処理パターン>

-- 0.カーソル取得用変数定義
DECLARE @c_key INT;
DECLARE @c_col1 NVARCHAR(50);
DECLARE @c_col2 INT;
DECLARE @c_col3 DATETIME2;

-- 1.カーソル定義
DECLARE cur1 CURSOR FOR SELECT key,col1,col2,col3 FROM tab1;

-- 2.カーソルOPEN
OPEN cur1;

-- 3.初回カーソルFETCH
FETCH NEXT FROM cur1 INTO @c_key,@c_col1,@c_col2,@c_col3;

-- 4.カーソルループ処理(取得結果なしで終了)
WHILE @@FETCH_STATUS = 0
BEGIN
-- @c_key,@c_col1,@c_col2,@c_col3とか使ってやりたい処理

-- 5.次の結果をフェッチする(内容は3と同じ)
FETCH NEXT FROM cur1 INTO @c_key,@c_col1,@c_col2,@c_col3;
END

-- 6.カーソルを閉じる
CLOSE cur1;
-- 7.解放
DEALLOCATE cur1;


だいたいこんな感じですが
いざ書こうと思ってももすぐ忘れる、書くのめんどくさい、特にフェッチする項目が多いときは超めんどくさい。
変更なんか入った日には。。
さらに今時のO/Rマッパとか糖衣構文とかに慣れ切った体ではほんとにつらい。

個人的に拒否反応が起こるところとしては

「0.カーソル取得用変数定義」
Oracleみたいに%ROWTYPEが使えればいいが、自分で定義しないといけない。
→いやいやレベル20%

「2.カーソルOPEN、3.初回カーソルFETCH」
読み込むのに手続きが多くてめんどくさい。
→いやいやレベル30%

「4.カーソルループ処理」
ここの「@FETCH_STATUS=0」っていうの毎回忘れるので調べるのめんどくさい。
→いやいやレベル35%

「5.次の結果をフェッチする」
3の初回カーソルと同じ内容をまた書かなければならない。いやすぎる。
→いやいやレベル55%

「6.カーソルを閉じる、7.解放」
まあ開いたら閉じるのが世の常なのでしょうがないケド。。開かなきゃ閉じなくてもいいのに。。
→いやいやレベル60%

ここまでは我慢の限界だとして、いざ変更が入ってカーソル取得項目が増えようもんなら
0の定義追加
1のカーソル定義変更
3のフェッチ項目追加
5のフェッチ項目追加
をやらなければならない
→いやいやレベル80%



自分がよく使うパターン
無限ループしないように気を付けるくらい。
(速度がどうのとか、リソースがこうのとか全く考えてません)

-- 1.処理用テーブル定義(カーソル定義に相当)
SELECT col1,col2,col3 INTO #w_tab1 FROM tab1;

-- 2.ワークテーブルなくなるまで順番に処理
WHILE EXISTS(SELECT * FROM #w_tab1)
BEGIN
DECLARE @c_key INT;
SET @c_key=select TOP 1 key from #w_tab1;

--処理で使いたい項目は上記と同様に#w_tab1から取得

-- 3.処理済データは削除(ここはWHILEの条件と合わせて更新でもなんでもよい)
DELETE FROM #w_tab1 WHERE key=@c_key;
END



ああ、すっきり。(自己満足)