我正在调用spring应用程序中的postgres存储过程,其中包含类型为text的一个IN参数和一个类型refcursor的INOUT参数。如何从CallableStatement以外的springboot应用程序调用此过程。
public class CallProc {
public static void main(String[] args) throws ClassNotFoundException, java.sql.SQLException {
Class.forName("org.postgresql.Driver");
String url = "jdbc:postgresql://azure.com/test";
Properties props = new Properties();
props.setProperty("user","test");
props.setProperty("password","test");
props.setProperty("ssl","true");
props.setProperty("escapeSyntaxCallMode", "callIfNoReturn");
Connection conn = DriverManager.getConnection(url, props);
// need a transaction
conn.setAutoCommit(false);
java.sql.CallableStatement callableStatement =
conn.prepareCall("{call myProc(?, ?)}");
callableStatement.setString(1, "user");
callableStatement.setObject(2, null);
callableStatement.registerOutParameter(2, java.sql.Types.REF_CURSOR);
callableStatement.execute();
java.sql.ResultSet rs =
(java.sql.ResultSet) callableStatement.getObject(2);
while (rs.next())
System.out.println(rs.getInt(1));
rs.close();
conn.commit();
conn.close();
}
}我的程序定义是这样的,
CREATE OR REPLACE PROCEDURE myapp.MyProc(
in_user_id TEXT,
INOUT user_roles refcursor)
language plpgsql
AS $BODY$
DECLARE
DERIVED USER_ID VARCHAR(50);
BEGIN
//body
...
//
END
$BODY$谢谢
发布于 2021-09-13 12:51:14
若要使用java.sql.CallableStatement调用过程,请使用带有值call或callIfNoReturn的连接参数escapeSyntaxCallMode,并且不指定返回参数。正如文献资料所说:
escapeSyntaxCallMode = String 指定驱动程序如何将JDBC转义调用语法转换为底层SQL,以调用过程或函数。在
escapeSyntaxCallMode=select模式下(默认情况下),驱动程序总是使用SELECT语句(只允许函数调用)。在escapeSyntaxCallMode=callIfNoReturn模式下,如果没有指定返回参数,驱动程序将使用调用语句(允许过程调用),否则驱动程序使用SELECT语句。在escapeSyntaxCallMode=call模式下,驱动程序总是使用CALL语句(只允许过程调用)。
问题是在v11中添加过程之前,JDBC驱动程序将CallableStatement调用转换为函数调用,而函数调用不适用于过程。
下面是一个调用过程p(IN integer, INOUT refcursor)的代码示例,其中refcursor位于integer的结果集上:
public class CallProc {
public static void main(String[] args) throws ClassNotFoundException, java.sql.SQLException {
Class.forName("org.postgresql.Driver");
java.sql.Connection conn =
java.sql.DriverManager.getConnection(
"jdbc:postgresql:test?user=laurenz&password=something&escapeSyntaxCallMode=callIfNoReturn"
);
// need a transaction
conn.setAutoCommit(false);
java.sql.CallableStatement callableStatement =
conn.prepareCall("{call p(?::text, ?::refcursor)}");
callableStatement.setInt(1, 5);
callableStatement.setObject(2, null);
callableStatement.registerOutParameter(2, java.sql.Types.REF_CURSOR);
callableStatement.execute();
java.sql.ResultSet rs =
(java.sql.ResultSet) callableStatement.getObject(2);
while (rs.next())
System.out.println(rs.getInt(1));
rs.close();
conn.commit();
conn.close();
}
}https://stackoverflow.com/questions/69160761
复制相似问题