ストアドで繰り返し処理

覚え書き。
テーブルA(TBL_A)の列1(COL_1)と、テーブルB(TBL_B)の列1(COL_1)を突き合わせて、
合致した場合、TBL_Aの列2(COL_2)の値をTBL_Bの列2(COL_2)に反映させるといった
更新処理を行う時

UPDATE TBL_B
SET TBL_B.COL2 = TBL_A.COL2
FROM TBL_A, TBL_B
WHERE TBL_A.COL1 = TBL_A.COL2

SQLで期待する結果になるが、仮にTBL_Aが3行あったとして

  1行目と合致した事により更新されたTBL_Bの行数 ・・・ 20行
  2行目と合致した事により更新されたTBL_Bの行数 ・・・ 30行
  3行目と合致した事により更新されたTBL_Bの行数 ・・・ 50行

だったとしても、結果は単に100行更新されたとしか返されないので、
行ごとの更新件数を出力するストアド。ここを参考にした。

ソース

CREATE PROCEDURE usp_TBL_B_UPDATE AS
BEGIN
-- 変数とカーソル宣言
	DECLARE @COL_1 VARCHAR(10)  -- TBL_Bと付き合わせる値を格納する変数
	DECLARE @COL_2 VARCHAR(50)  -- TBL_Bに反映させる値を格納する変数
	DECLARE csr_TBL_A CURSOR FOR
		SELECT COL_1, COL_2 FROM TBL_A

-- 処理件数を返させない
	SET NOCOUNT ON

-- 実処理
	OPEN csr_TBL_A -- カーソルを開く

	-- カーソルを進めて各列の値を変数に格納
	-- 09/02/24修正 OPEN の前に FETCH NEXT があったのを OPEN の後にした
	FETCH NEXT FROM csr_TBL_A INTO @COL_1, @COL_2

	-- カーソルのステータスがゼロの間、ループ
	WHILE @@FETCH_STATUS = 0
	BEGIN
		-- TBL_Bを更新
		UPDATE TBL_B
		SET TBL_B.COL_2 = @COL_2
		WHERE
		TBL_B.COL_1 = @COL_1

		-- メッセージを返す ※CHAR(9) = タブ文字
		PRINT @COL_1 + CHAR(9) + CAST(@@ROWCOUNT AS VARCHAR(10))

		-- カーソルを進めて各列の値を変数に格納
		FETCH NEXT FROM csr_TBL_A INTO @COL_1, @COL_2

	END

	-- カーソルのクローズ & 参照の削除
	CLOSE csr_TBL_A -- 09/02/24 間違ってたんで修正 CSR_MODEL_NO → csr_TBL_A
	DEALLOCATE csr_TBL_A -- 09/02/24 間違ってたんで修正 CSR_MODEL_NO → csr_TBL_A

END

MSDN

FETCH
WHILE
DEALLOCATE
あとは

ISQL -U SA -P HOGE -S SRV_HOGE -d DB_HOGE -Q "usp_TBL_B_UPDATE" > hoge.log

といった感じでバッチ起動する感じ。