延續上一篇無回傳值預存程序,本文聚焦 帶 OUT 參數的預存程序,示範如何在 Java 中註冊輸出參數型別、執行後取回回傳值,並解析多輸出參數、型別對應與常見陷阱。
CREATE OR REPLACE PROCEDURE TESTB (
PARA1 IN VARCHAR2,
PARA2 OUT VARCHAR2
) AS
BEGIN
SELECT I_NAME INTO PARA2 FROM TESTTB WHERE I_ID = PARA1;
END TESTB;
關鍵點:
PARA2 OUT VARCHAR2 宣告為輸出參數,供呼叫端接收查詢結果。SELECT ... INTO 將查詢單一值直接賦給 OUT 參數。NO_DATA_FOUND,建議在程序內以 EXCEPTION WHEN NO_DATA_FOUND THEN PARA2 := NULL; 處理。package com.hyq.src;
import java.sql.*;
import oracle.jdbc.OracleTypes; // 需匯入 Oracle 擴充型別
public class TestProcedureTwo {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";
String user = "hyq";
String pwd = "hyq";
try (Connection conn = DriverManager.getConnection(url, user, pwd);
CallableStatement cstmt = conn.prepareCall("{call HYQ.TESTB(?,?)}")) {
// 1. 綁定 IN 參數
cstmt.setString(1, "100");
// 2. 關鍵:註冊 OUT 參數型別(索引 2 對應 PARA2)
cstmt.registerOutParameter(2, OracleTypes.VARCHAR);
// 3. 執行
cstmt.execute();
// 4. 取回 OUT 參數值
String result = cstmt.getString(2);
System.out.println("回傳值 = " + result);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
java.sql.Types 或 oracle.jdbc.OracleTypes 常數。
| Oracle 型別 | 註冊常數 | 取值方法 |
|---|---|---|
| VARCHAR2 / CHAR | Types.VARCHAR / OracleTypes.VARCHAR | getString() |
| NUMBER | Types.NUMERIC / OracleTypes.NUMBER | getBigDecimal() / getLong() |
| DATE | Types.DATE / OracleTypes.DATE | getDate() / getTimestamp() |
| CURSOR (REF CURSOR) | OracleTypes.CURSOR | getObject() 轉 ResultSet |
-- 程序定義
CREATE OR REPLACE PROCEDURE MULTI_OUT (
P_ID IN NUMBER,
P_NAME OUT VARCHAR2,
P_SAL OUT NUMBER,
P_HIRE OUT DATE
) AS ...
-- Java 端
cstmt.registerOutParameter(2, OracleTypes.VARCHAR);
cstmt.registerOutParameter(3, OracleTypes.NUMBER);
cstmt.registerOutParameter(4, OracleTypes.DATE);
cstmt.execute();
String name = cstmt.getString(2);
BigDecimal sal = cstmt.getBigDecimal(3);
Date hire = cstmt.getDate(4);
索引位置嚴格對應程序定義順序,切勿依名稱推斷。
-- 程序:輸入薪資,回傳調整後薪資
CREATE OR REPLACE PROCEDURE ADJUST_SAL (
P_EMPNO IN NUMBER,
P_SAL IN OUT NUMBER
) AS
BEGIN
SELECT SAL * 1.1 INTO P_SAL FROM EMP WHERE EMPNO = P_EMPNO;
END;
// Java:先 set 再 registerOutParameter
cstmt.setBigDecimal(2, new BigDecimal("50000")); // 輸入值
cstmt.registerOutParameter(2, OracleTypes.NUMBER); // 登記輸出
cstmt.execute();
BigDecimal newSal = cstmt.getBigDecimal(2); // 取回調整後值
registerOutParameter 或 getString 索引超出參數總數,核對程序定義順序。ResultSet 必須 close()。掌握 OUT 參數註冊與取值機制,即可在 Java 中靈活呼叫 Oracle 函式化業務邏輯,實現資料查詢、計算結果的高效回傳。