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

JDBC 核心教程:CallableStatement 調用儲存過程完整指南

     編輯:Java 相關知識

CallableStatement 核心定位

提供標準化、跨 DBMS 的儲存過程調用介面。繼承 Statement (通用 SQL) 與 PreparedStatement (IN 參數),新增 OUT/INOUT 參數處理能力。

調用語法標準 (JDBC Escape Syntax)

{call 過程名[(?, ?, ...)]}
{? = call 過程名[(?, ?, ...)]}  -- 有返回值 (函數)
{call 過程名}                    -- 無參數

方括號內為可選,實際 SQL 不含方括號。? 為參數佔位符 (IN/OUT/INOUT)。

DatabaseMetaData 檢測支援度

  • supportsStoredProcedures():是否支援儲存過程。
  • getProcedures():獲取儲存過程元資料描述。

核心操作三步驟

  1. 建立 CallableStatement:
    CallableStatement cstmt = con.prepareCall("{call getTestData(?, ?)}");
  2. 註冊 OUT/INOUT 參數 JDBC 型別 (必須在執行前):
    cstmt.registerOutParameter(1, Types.TINYINT);        // 第 1 參數 OUT
    cstmt.registerOutParameter(2, Types.DECIMAL, 3);     // 第 2 參數 OUT,小數 3 位

    registerOutParameter 使用 JDBC 型別 (java.sql.Types) 對應資料庫返回型別。

  3. 設置 IN/INOUT 參數值、執行、獲取 OUT 結果:
    // 設置 IN 參數 (繼承 PreparedStatement setXXX)
    cstmt.setInt(1, 100);
    
    // 執行
    boolean hasResultSet = cstmt.execute(); // 或 executeQuery/update
    
    // 獲取 OUT 參數 (getXXX 對應 Java 型別)
    byte b = cstmt.getByte(1);
    BigDecimal bd = cstmt.getBigDecimal(2);

INOUT 參數完整範例

儲存過程 reviseTotal(INOUT total TINYINT):

CallableStatement cstmt = con.prepareCall("{call reviseTotal(?)}");
cstmt.setByte(1, 25);                    // 設置 IN 值
cstmt.registerOutParameter(1, Types.TINYINT); // 註冊 OUT 型別 (需一致)
cstmt.executeUpdate();
byte newVal = cstmt.getByte(1);          // 獲取更新後的值

結果集與 OUT 參數獲取順序 (可移植性關鍵)

建議順序:先處理所有 ResultSet (含多結果集循環 getResultSet()/getUpdateCount()/getMoreResults()),最後讀取 OUT 參數。某些 DBMS 要求此順序。

OUT 參數 NULL 值處理

資料庫返回 JDBC NULL 時,getXXX 轉換為 Java null/0/false。判斷真實 NULL 唯一方法:緊隨 getXXX 後調用 wasNull(),返回 true 表示原值為 NULL。

最佳實踐提醒

  • 儲存過程邏輯下沉資料庫層,應用層僅調用,利於效能與安全。
  • 大量數據處理優先考慮批次操作 (addBatch/executeBatch) 而非單條儲存過程。
  • OUT 參數型別註冊必須與資料庫定義嚴格一致,避免隱式轉換錯誤。
  • 使用連線池時注意 CallableStatement 狀態重置 (clearParameters)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved