首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 呼叫 Oracle 預存程序通用模式:ADO + Package + Ref Cursor 完整實現

     編輯:VC 教學

連接字串:必須用 OLE DB Provider


// 錯誤:ODBC
"Driver={Microsoft ODBC for Oracle};Server=ORCL;Uid=scott;Pwd=tiger;"

// 正確:MSDAORA
"Provider=MSDAORA.1;Password=tiger;User ID=scott;Data Source=ORCL;Persist Security Info=True"

Oracle 預存程序回傳結果集:SYS_REFCURSOR

CREATE OR REPLACE PACKAGE pkg_emp AS
    TYPE t_cursor IS REF CURSOR;
    PROCEDURE get_emp(p_deptno NUMBER, p_rc OUT t_cursor);
END pkg_emp;
/

CREATE OR REPLACE PACKAGE BODY pkg_emp AS
    PROCEDURE get_emp(p_deptno NUMBER, p_rc OUT t_cursor) IS
    BEGIN
        IF p_deptno = 0 THEN
            OPEN p_rc FOR SELECT empno, ename, job, sal FROM emp;
        ELSE
            OPEN p_rc FOR SELECT empno, ename, job, sal FROM emp WHERE deptno = p_deptno;
        END IF;
    END get_emp;
END pkg_emp;
/

或無 Package 直接:PROCEDURE get_emp(p_deptno NUMBER, p_rc OUT SYS_REFCURSOR)。

VC++ ADO 呼叫代碼(通用模式)


_ConnectionPtr pConn(__uuidof(Connection));
pConn->Open(_bstr_t(connStr), L"", L"", adConnectUnspecified);

_RecordsetPtr pRs(__uuidof(Recordset));
// 關鍵:ODBC CALL 語法,輸出參數省略
pRs->Open(_bstr_t("{call pkg_emp.get_emp(10)}"),
          _variant_t((IDispatch*)pConn),
          adOpenStatic, adLockReadOnly, adCmdText);

// 處理多結果集 (Oracle 只回一個 Ref Cursor,但通用寫法)
long recordsAffected = 0;
while (pRs) {
    while (!pRs->EndOfFile) {
        // 讀取欄位...
        pRs->MoveNext();
    }
    pRs = pRs->NextRecordset(&recordsAffected);
}
pRs->Close();
pConn->Close();

統一 SQL Server / Oracle 語法

採用 {call proc_name(param1, param2, ...)} 格式:

  • SQL Server:{call get_emp(10)} (輸出參數同樣可省略)。
  • Oracle:{call pkg_emp.get_emp(10)}。

VC++ 代碼**零修改**支援雙資料庫,僅換連接字串與 SQL 字串常數。

進階:帶 OUTPUT 參數的預存程序


// SQL Server 風格 (Oracle 同理)
DECLARE @ret INT, @msg NVARCHAR(200);
EXEC check_login 'admin', 'pwd', @ret OUTPUT, @msg OUTPUT;
SELECT @ret AS RetCode, @msg AS Msg;

ADO 執行上述批次 SQL,結果集包含 RetCode、Msg 兩欄,統一用 pRs->Fields->GetItem() 讀取。

效能與穩定性提醒

  • adCmdText 而非 adCmdStoredProc,避免 ADO 內部參數探查開銷。
  • CursorLocation = adUseClient 客戶端游標,支援斷開連線後操作 Recordset。
  • 連線池:pConn->ConnectionString 含 OLE DB Services=-1 (預設啟用池化)。
  • 錯誤處理:_com_error 捕獲 HRESULT,記錄 ErrorInfo->GetDescription()。

此模式已在多個生產系統穩定運行 10+ 年,核心優勢在於 SQL 字串即介面契約,VC++ 層完全解耦預存程序簽名變更。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved