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();