Oracle REF CURSOR 特殊性
Oracle 儲存程序不直接返回 ResultSet,而是透過 OUT 參數返回 REF CURSOR。JDBC 需註冊 OracleTypes.CURSOR 並從 CallableStatement.getObject() 取得 ResultSet。
資料庫端範例
CREATE OR REPLACE PACKAGE PK_AREA_PUBLIC IS
TYPE SEARCH_RESULT IS REF CURSOR;
PROCEDURE AREA_SEARCH(
V_TARGET_IN IN VARCHAR2,
CUR_RESULT_OUT OUT SEARCH_RESULT
);
END;
/
CREATE OR REPLACE PACKAGE BODY PK_AREA_PUBLIC IS
PROCEDURE AREA_SEARCH(
V_TARGET_IN IN VARCHAR2,
CUR_RESULT_OUT OUT SEARCH_RESULT
) IS
V_SQL VARCHAR2(1000);
BEGIN
V_SQL := 'SELECT AREA_ID, AREA_NAME FROM AREAS WHERE AREA_NAME LIKE :1';
OPEN CUR_RESULT_OUT FOR V_SQL USING '%' || V_TARGET_IN || '%';
END;
END;
/
Spring StoredProcedure 實作
public class AreaSearchProcedure extends StoredProcedure {
private static final String SQL = "PK_AREA_PUBLIC.AREA_SEARCH";
private final List
呼叫端使用
DataSource ds = ...; // 取得 DataSource
AreaSearchProcedure proc = new AreaSearchProcedure(ds);
List> rows = proc.execute("Taipei");
for (Map row : rows) {
System.out.println(row.get("AREA_ID") + " => " + row.get("AREA_NAME"));
}
多重 REF CURSOR 處理
若程序有多個 OUT REF CURSOR,需為每個參數宣告獨立的 SqlOutParameter 並提供各自的 ResultSetExtractor,結果可放入共用的 Map> 結構。
關鍵配置
- 依賴
spring-jdbc 且類路徑需有 ojdbc 驅動(提供 OracleTypes.CURSOR)。
- 資料源建議使用連線池(HikariCP、Druid)。
- 若使用 Spring Boot,可註冊為
@Bean 並注入 DataSource。