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();
所有适用于 Statement 和 PreparedStatement 的注意事项都适用于 CallableStatement,同时你还需要考虑一些额外的限制:
你只能在一个事务里面调用一个存储过程。
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();