带有PostgreSQL参数名称的CallableStatement

时间:2013-11-01 05:18:33

标签: java postgresql jdbc

我尝试调用指定了参数名称的存储过程,但JDBC无法接受这些参数。它说:

Method org.postgresql.jdbc4.Jdbc4CallableStatement.setObject(String,Object) is not yet implemented.

我使用postgresql-9.2-1003.jdbc4

我还有其他办法吗?

我知道我只能指定序列号。但我想指定参数名称,因为这样做更方便。

我的代码:

String call_statement = "{ ? = call procedure_name(?, ?, ?) }";            
CallableStatement proc = connection.prepareCall(call_statement);
proc.registerOutParameter(1, Types.OTHER);            
proc.setObject("param1", 1);
proc.setObject("param2", "hello");
proc.setObject("param3", true);
proc.execute();
ResultSet result = (ResultSet)proc.getObject(1);

2 个答案:

答案 0 :(得分:2)

不幸的是,使用参数名称不是PostgreSQL数据库的JDBC 4驱动程序实现所支持的功能。请参阅code中的此JDBC 4实现的GrepCode

但是,您仍然可以继续使用整数(变量或文字)来指示参数的位置。

答案 1 :(得分:0)

现在是2020年,用于Postgres的标准开源JDBC驱动程序仍然不支持CallableStatement的命名参数符号。

有趣的是, EnterpriseDB 驱动程序does support it(我曾说过-我尝试使用EDB JDBC驱动程序-它确实支持命名参数,但是它做了很多不同的事情,如果有的话,我们出于其他原因完全排除了此选项)

对我们有用的解决方案-使用此“ hack”(伪代码,YMMV):

String sql = "SELECT * FROM PROC(IN_PARAM1 => ?, IN_PARAM2 => ?, IN_PARAM => ?)";            
PreparedStatement ps = connection.prepareStatement(sql);
ps.setObject("IN_PARAM1", 1);
ps.setObject("IN_PARAM2", "hello");
ps.setObject("IN_PARAM3", true);
ps.execute();
ResultSet result = (ResultSet)ps.getObject(1);

此符号的杀手级功能-能够使用可选的参数调用SP(可以通过具有可选的 ordinal 参数来实现,但是,如果您拥有多个可选的参数,则可以成为-一场噩梦,因为一个人需要通过太多nulls,以致于容易误算,而且很难发现这些错误)

还有其他好处,例如返回多个ResultSets(反射器)的能力,将地图用作参数的能力等。

P.S .:对于Node.jsnode-postgres,我们也使用相同的技巧-效果很好。