首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JDBC 取得 Oracle 預存程序動態結果集:REF CURSOR 完整實戰指南

     編輯:Java 相關知識

背景差異:SQL Server vs Oracle

SQL Server/Sybase:預存程序結尾直接 SELECT ... 即可回傳結果集。
Oracle:必須使用 REF CURSOR 游標變數 回傳結果集。

完整實作步驟

1. 資料表結構

CREATE TABLE hotline (country VARCHAR2(50), pno VARCHAR2(50));

2. 套件規格與主體 (PL/SQL)

CREATE OR REPLACE PACKAGE PKG_HOTLINE IS
    TYPE HotlineCursorType IS REF CURSOR;
    FUNCTION getHotline RETURN HotlineCursorType;
END PKG_HOTLINE;

CREATE OR REPLACE PACKAGE BODY PKG_HOTLINE IS
    FUNCTION getHotline RETURN HotlineCursorType IS
        hotlineCursor HotlineCursorType;
    BEGIN
        OPEN hotlineCursor FOR SELECT * FROM hotline;
        RETURN hotlineCursor;
    END;
END PKG_HOTLINE;
  • 定義 TYPE ... IS REF CURSOR 建立游標型別
  • 函數回傳該型別,OPEN ... FOR SELECT 綁定查詢

3. SQL*Plus 測試驗證

VAR rs REFCURSOR;
EXEC :rs := PKG_HOTLINE.getHotline;
PRINT rs;

4. Java 呼叫核心代碼

public void openCursor() {
    Connection conn = null;
    ResultSet rs = null;
    CallableStatement stmt = null;
    String sql = "{? = call PKG_HOTLINE.getHotline()}";

    try {
        conn = getConnection(); // 自行實作
        stmt = conn.prepareCall(sql);
        stmt.registerOutParameter(1, OracleTypes.CURSOR); // 關鍵:註冊 CURSOR 型別
        stmt.execute();
        rs = ((OracleCallableStatement) stmt).getCursor(1); // 取得 ResultSet

        while (rs.next()) {
            String country = rs.getString(1);
            String pno = rs.getString(2);
            System.out.println("country:" + country + "|pno:" + pno);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        closeConnection(conn, rs, stmt); // 自行實作資源關閉
    }
}

關鍵技術點總結

  1. CallableStatement:呼叫預存函數/程序
  2. registerOutParameter(index, OracleTypes.CURSOR):註冊輸出參數為 REF CURSOR
  3. OracleCallableStatement.getCursor(index):將 REF CURSOR 轉為標準 ResultSet
  4. 後續操作與普通 ResultSet 完全一致

適用場景與替代方案

  • 適用:必須在資料庫端封裝複雜查詢邏輯、動態構建查詢、大量資料分頁遊標
  • 替代:簡單查詢優先使用 PreparedStatement 直寫 SQL,減少資料庫端負擔與網路往返

避坑提醒

  • 需引入 oracle.jdbc.OracleTypes、oracle.jdbc.OracleCallableStatement(廠商專用類)
  • 確保 JDBC 驅動版本與資料庫版本相容
  • ResultSet 使用完畢必須關閉,避免資料庫端遊標洩漏
  • 大量資料考慮分批抓取 (setFetchSize) 提升效能
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved