/*
以 DB2 的語法來實現像 Oracle Ref cursor的做法:
宣告: DECLARE cursorname CURSOR [WITH HOLD] WITH RETURN FOR CUR1;
程式主體:PREPARE CUR1 FROM dynamic string;
開啟: cursor OPEN cursorname;
My scenario:
1. 建立一個測試 table, 存放日期,年,月,日
2. 運用Session global variable存放年份,做為dynamic string裡的年度條件
3. DB2 procedure 裡傳回單一resultset及cursor的語法
4. 測試結果
*/
/* 建立測試table及運用CTE與Recursive SQL新增日期資料 */
CREATE TABLE T3
(
DT INTEGER,
YEAR_N INTEGER,
MONTH_N INTEGER,
DAY_N INTEGER
) IN USERSPACE1;
INSERT INTO T3
WITH N(COL1)
AS
(SELECT DATE('2000-01-01') FROM SYSIBM.DUAL
UNION ALL
SELECT COL1 + 1 DAY FROM N
WHERE YEAR(COL1 + 1 DAY) <= 2010
)
SELECT INT(COL1),YEAR(COL1),MONTH(COL1),DAY(COL1) FROM N
/* 建立session global variable */
CREATE VARIABLE ADMINISTRATROR.YEAR_SET INTEGER
-- 給定值為2009
SET ADMINISTRATROR.YEAR_SET = 2009
/* 附帶說明:只有相同 session 才看得到 session global variable 設定值
測試再另使用db2cmd去看這個year_set
*/
C:\>db2 connect to orion
資料庫連線資訊
資料庫伺服器 = DB2/NT 9.7.0
SQL 授權 ID = ADMINIST...
本端資料庫別名 = ORION
C:\>db2 values administrator.year_set
1
-----------
-
已選取 1 個記錄。
/* 建立 procedure sp_test 傳回一個 result */
CREATE PROCEDURE SP_TEST
RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE retcode INTEGER DEFAULT 0;
DECLARE szSql VARCHAR(128);
DECLARE TIMECUR CURSOR WITH HOLD WITH RETURN FOR CUR1;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION,
SQLWARNING,
NOT FOUND
SET retcode = SQLCODE;
SET szSql = 'SELECT DT FROM T3 WHERE YEAR_N = YEAR_SET';
PREPARE CUR1 FROM szSql;
OPEN TIMECUR;
END
/* 測試(需傳回所有2009年的日期) */
C:\>db2 call sp_test
結果集 1
--------------
DT
-----------
20090101
20090102
20090103
20090104
20090105
20090106
20090107
20090108
20090109
20090110
20090111
.
.
.