31.5. 調用存儲過程

PostgreSQL's JDBC 驅動完全支持調用 PostgreSQL 存儲過程。

Example 31-4. 調用一個內置的存儲函數

這個例子顯示了如何調用一個 PostgreSQL 內置的函數, upper,它只是簡單地把你提供的字串參數轉換成大寫。

// 關閉事務
con.setAutoCommit(false);
// 過程調用
CallableStatement upperProc = con.prepareCall("{ ? = call upper( ? ) }");
upperProc.registerOutParameter(1, Types.VARCHAR);
upperProc.setString(2, "lowercase to uppercase");
upperProc.execute();
String upperCased = upperProc.getString(1);
upperProc.close();

31.5.1. 使用 CallableStatement 接口

所有適用于 StatementPreparedStatement 的注意事項都適用于 CallableStatement,同時你還需要考慮一些額外的限制:

31.5.2. 從個存儲過程裡獲取 ResultSet

PostgreSQL 的存儲過程可以通過一個 refcursor 值返回結果集。

作為 JDBC 的擴展,PostgreSQL JDBC 驅動可以將 refcursor 值作為 ResultSet 值返回。

Example 31-5. 從一個函數裡獲取 refcursor

在調用一個返回 refcursor 的函數時,你必須把返回類型 getObject 轉換成 ResultSet

// 關閉自動提交事務
con.setAutoCommit(false);
// 過程調用
CallableStatement proc = con.prepareCall("{ ? = call doquery ( ? ) }");
proc.registerOutParameter(1, Types.Other);
proc.setInt(2, -1);
proc.execute();
ResultSet results = (ResultSet) proc.getObject(1);
while (results.next()) {
  // 處理結果集
}
results.close();
proc.close();

我們也可能把返回值 refcursor 看作一種特殊的類型。 JDBC 驅動提供了 org.postgresql.PGRefCursorResultSet 用于這個目的。

Example 31-6. 把 refcursor 當作獨立的類型

con.setAutoCommit(false);
CallableStatement proc = con.prepareCall("{ ? = call doquery ( ? ) }");
proc.registerOutParameter(1, Types.Other);
proc.setInt(2, 0);
org.postgresql.PGRefCursorResultSet refcurs
    = (PGRefCursorResultSet) con.getObject(1);
String cursorName = refcurs.getRefCursor();
proc.close();