Oracle 8i 無隱性結果集,**必須使用 REF CURSOR (弱類型/強類型游標) 作為 OUT 參數** 返回查詢結果給呼叫端 (Java/VFP/.NET 等)。
CREATE OR REPLACE PACKAGE SMSMAINT AS
TYPE T_CURSOR IS REF CURSOR; -- 弱類型游標
PROCEDURE GetAgtBankFlow(
AreaCode IN VARCHAR2,
KeyWord IN VARCHAR2,
StartTradeDate IN VARCHAR2,
EndTradeDate IN VARCHAR2,
Re_CURSOR OUT T_CURSOR,
Ret OUT NUMBER);
PROCEDURE GetAgtBalance(
AreaCode IN VARCHAR2,
KeyWord IN VARCHAR2,
Re_CURSOR OUT T_CURSOR,
Ret OUT NUMBER);
END SMSMAINT;
-- 檢查 GTT 是否存在,不存在則建立 (ON COMMIT PRESERVE ROWS 保留跨 Commit 可見)
SELECT COUNT(*) INTO IsExists FROM ALL_TABLES WHERE TABLE_NAME = 'TEMPAGTBANKFLOW';
IF IsExists = 0 THEN
EXECUTE IMMEDIATE q'[
CREATE GLOBAL TEMPORARY TABLE SMS_PAY.TEMPAGTBANKFLOW (
AGTID VARCHAR2(13), BANK_GLIDE NUMBER(12), ...
) ON COMMIT PRESERVE ROWS]';
ELSE
EXECUTE IMMEDIATE 'TRUNCATE TABLE SMS_PAY.TEMPAGTBANKFLOW';
END IF;
strSQL := 'INSERT INTO TEMPAGTBANKFLOW SELECT ... FROM ... WHERE 1=1';
IF AreaCode != '0' THEN strSQL := strSQL || ' AND TRIM(C.AREACODE) = ''' || AreaCode || ''''; END IF;
IF StartTradeDate IS NOT NULL THEN ... END IF;
IF KeyWord IS NOT NULL THEN ... END IF;
EXECUTE IMMEDIATE strSQL;
OPEN Re_CURSOR FOR 'SELECT * FROM SMS_PAY.TEMPAGTBANKFLOW ORDER BY AGTID';
Ret := 0;
RETURN;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
Ret := 999;
RETURN;
FstCursor 依條件查詢。TEMPAGTBALANCE。OPEN Re_CURSOR FOR SELECT * FROM TEMPAGTBALANCE 返回。((OracleCallableStatement)cstmt).getCursor(n) 取得 ResultSet。((OracleRefCursor)param.Value).GetDataReader()。SQLEXEC(nh, "{call pkg.proc(?, ?)}", "cursor_name") 直接映射到 VFP 游標。ORA-08103。q'[...]' 替代引號雙重轉義,提升可讀性。DBMS_ASSERT。