T-SQLのカーソル宣言は,PL/SQLと異なり,プログラム中の宣言する位置が動作に影響を与えます。
PL/SQL実装になれた方ですと,T-SQLで以下のようなプログラムを記述する可能性があります。
しかし,このプログラムは期待通りには,動作しません。なぜでしょうか。なぜなら,カーソル宣言時には,変数@DEL_FLG_ACTIVEに値が代入されていないからです。T-SQLではカーソル内で使用される変数値も含めて,カーソル宣言時にその内容が取得されます。そのため,カーソルのOPEN時に変数が再評価されると言うことがありません。
以上のようなT-SQLのカーソル特性は,カーソル処理のネストを1ストアド内で記述する場合にPL/SQLと大きく異なるコーディングを求めます。論理コードで示すと,以下のように親カーソルループ内に,子カーソルの宣言と子カーソルの破棄を記述する必要が生じます。
DECLARE 親カーソル
OPEN 親カーソル
WHILE 親カーソルループ BEGIN
DECLARE 子カーソル(当然親カーソルの値が利用される)
OPEN 子カーソルオープン
WHILE 子カーソルループ BEGIN
何らかの処理
END 子カーソルループ
CLOSE 子カーソル
DEALLOCATE 子カーソル
END 親カーソルループ
CLOSE 親カーソル
DEALLOCATE 親カーソル
カーソルのネスト構造というのは,ストアド処理の中では,比較的よく現れるものです。ただでさえ,コード量が増えるT-SQLですが,ループ内で子カーソル宣言や破棄を書いていると,自分が何をしているのか,わからなくなるときがあります。T-SQLの限界といえば,それまでですが,何とかして欲しい部分です。
このようなわけで,T-SQLには引数付きのカーソル宣言というものも存在しません。とても便利な機能なので,T-SQLでも実装して欲しいのですけどね。
PL/SQL実装になれた方ですと,T-SQLで以下のようなプログラムを記述する可能性があります。
0001 -- 変数宣言0002 DECLARE @DEL_FLG_ACTIVE INT; -- 未削除フラグ値0003 DECLARE @DEL_FLG_DELETED INT; -- 未削除フラグ値0004 0005 DECLARE @CUSTOMER_ID DECIMAL(12, 0),0006 @CUSTOMER__NAME VARCHAR(50),0007 @ADDRESS_ID DECIMAL(12, 0),0008 @CONTACT_ID DECIMAL(12, 0),0009 @DEL_FLG DECIMAL(1, 0),0010 @CREATED_BY VARCHAR(10),0011 @CREATION_DATE DATETIME,0012 @LAST_UPDATE_BY VARCHAR(10),0013 @LAST_UPDATE_DATE DATETIME0014 0015 DECLARE my_cursor CURSOR FAST_FORWARD READ_ONLY 0016 FOR0017 SELECT CUSTOMER_ID,0018 CUSTOMER__NAME,0019 ADDRESS_ID,0020 CONTACT_ID,0021 DEL_FLG,0022 CREATED_BY,0023 CREATION_DATE,0024 LAST_UPDATE_BY,0025 LAST_UPDATE_DATE0026 FROM BLOGDB.BLOG.M_CUSTOMERS0027 WHERE DEL_FLG = @DEL_FLG_ACTIVE0028 AND CREATED_BY > DATEADD(DAY, -1, GETDATE())0029 ;0030 0031 -- 初期設定0032 SET @DEL_FLG_ACTIVE = 0;0033 SET @DEL_FLG_DELETED = 1;0034 0035 OPEN my_cursor
しかし,このプログラムは期待通りには,動作しません。なぜでしょうか。なぜなら,カーソル宣言時には,変数@DEL_FLG_ACTIVEに値が代入されていないからです。T-SQLではカーソル内で使用される変数値も含めて,カーソル宣言時にその内容が取得されます。そのため,カーソルのOPEN時に変数が再評価されると言うことがありません。
以上のようなT-SQLのカーソル特性は,カーソル処理のネストを1ストアド内で記述する場合にPL/SQLと大きく異なるコーディングを求めます。論理コードで示すと,以下のように親カーソルループ内に,子カーソルの宣言と子カーソルの破棄を記述する必要が生じます。
DECLARE 親カーソル
OPEN 親カーソル
WHILE 親カーソルループ BEGIN
DECLARE 子カーソル(当然親カーソルの値が利用される)
OPEN 子カーソルオープン
WHILE 子カーソルループ BEGIN
何らかの処理
END 子カーソルループ
CLOSE 子カーソル
DEALLOCATE 子カーソル
END 親カーソルループ
CLOSE 親カーソル
DEALLOCATE 親カーソル
カーソルのネスト構造というのは,ストアド処理の中では,比較的よく現れるものです。ただでさえ,コード量が増えるT-SQLですが,ループ内で子カーソル宣言や破棄を書いていると,自分が何をしているのか,わからなくなるときがあります。T-SQLの限界といえば,それまでですが,何とかして欲しい部分です。
このようなわけで,T-SQLには引数付きのカーソル宣言というものも存在しません。とても便利な機能なので,T-SQLでも実装して欲しいのですけどね。