在企業級 Java 應用中,呼叫 Oracle 預存程序執行資料操作(INSERT/UPDATE/DELETE)是常見需求。本文以「無回傳值」預存程序為例,完整示範從資料庫端建立程序、Java 端使用 CallableStatement 呼叫、參數綁定、異常處理到資源釋放的標準化流程,並說明關鍵細節與最佳實踐。
CREATE OR REPLACE PROCEDURE TESTA (
PARA1 IN VARCHAR2,
PARA2 IN VARCHAR2
) AS
BEGIN
INSERT INTO HYQ.B_ID (I_ID, I_NAME) VALUES (PARA1, PARA2);
END TESTA;
說明:
IN 模式參數,無 OUT / IN OUT 參數。INSERT,提交由呼叫端控制(預設自動提交或手動 conn.commit())。HYQ.B_ID (I_ID, I_NAME)。package com.hyq.src;
import java.sql.*;
public class TestProcedureOne {
public static void main(String[] args) {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";
String user = "hyq";
String password= "hyq";
Connection conn = null;
CallableStatement cstmt = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
// 1. 準備呼叫語法:{call 程序名(?,?)}
String sql = "{call HYQ.TESTA(?,?)}";
cstmt = conn.prepareCall(sql);
// 2. 綁定 IN 參數(索引從 1 開始)
cstmt.setString(1, "100");
cstmt.setString(2, "TestOne");
// 3. 執行
cstmt.execute();
System.out.println("預存程序執行成功");
} catch (ClassNotFoundException e) {
System.err.println("找不到 JDBC 驅動類別:" + e.getMessage());
} catch (SQLException e) {
System.err.println("資料庫錯誤:" + e.getMessage());
e.printStackTrace();
} finally {
// 4. 依序關閉資源(避免洩漏)
closeQuietly(cstmt);
closeQuietly(conn);
}
}
private static void closeQuietly(AutoCloseable resource) {
if (resource != null) {
try { resource.close(); } catch (Exception ignore) {}
}
}
}
{call ...},跨資料庫可攜性較好。{call SCHEMA.PROC_NAME(?,?)}。| Oracle 型別 | Java setter | 備註 |
|---|---|---|
| VARCHAR2 / CHAR | setString | 最常用 |
| NUMBER | setInt / setLong / setBigDecimal | 視精度選擇 |
| DATE / TIMESTAMP | setDate / setTimestamp | 需 java.sql.* 型別 |
| CLOB / BLOB | setClob / setBlob | 大物件需分塊處理 |
autoCommit=true(預設),execute() 後立即提交。conn.setAutoCommit(false),執行完多個程序後 conn.commit(),異常時 conn.rollback()。try (Connection conn = DriverManager.getConnection(url, user, password);
CallableStatement cstmt = conn.prepareCall("{call HYQ.TESTA(?,?)}")) {
cstmt.setString(1, "100");
cstmt.setString(2, "TestOne");
cstmt.execute();
} catch (SQLException e) {
e.printStackTrace();
}
此寫法自動關閉 Connection、CallableStatement,程式碼更簡潔安全。
ojdbc8.jar(或對應版本)已在 Classpath。jdbc:oracle:thin:@host:port:service_name、防火牆、監聽器。掌握此標準流程,即可在 Java 應用中穩健、高效地呼叫 Oracle 無回傳值預存程序,滿足批次處理、資料同步等企業級需求。