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