JDBC:批处理中带有返回值的ORCLE存储过程

时间:2019-02-19 11:34:30

标签: oracle jdbc plsql

我有一个JDBC连接到Oracle RDBMS。

我需要调用一个存储过程(将其命名为foo),该存储过程返回一个数字。

如果我自己执行每条语句,效果很好。

for (int i = 0; i < 10;i ++)
{
  CallableStatement cst = con.prepareCall ("{? = foo (" + i + ")}");
  cst.registerOutParameter (1, Types.INTEGER);
  cst.execute ();
}

现在,我喜欢使用批处理来提高性能。那就是我的方法。

Statement st = con.createStatement ();
for (int i = 0; i < 10;i ++)
{
  st.addBatch ("{? = foo (" + i + ")}");
}
st.executeBatch ();

那行不通。

错误告诉我,并非每个变量都被分配。认为这是因为没有返回值的注册,就像上面的工作示例一样。

如果我将语句设置为

{foo (" + i + ")}

删除返回值,然后我得到未定义过程的错误。

在批处理中如何处理具有返回值的存储过程?

1 个答案:

答案 0 :(得分:1)

JDBC批处理需要相同的准备语句和一堆绑定变量。

您通过为每个"{? = foo (" + i + ")}"生成的动态语句i违反了此规定。

您必须使用带有两个绑定变量"{? = foo (?)}"

的单个语句

不幸的是,这导致了异常

  

捕获:java.sql.SQLException:不允许操作:无法对带有out或inout参数的存储过程进行批处理

因为不可能从批处理语句返回结果函数调用的集合。

幸运的是,有一个非常简单的替代解决方案。您可以使用prepareStatement模拟批处理 (即,您将往返次数限制为数据库服务器)

 def stmt = con.prepareStatement("select foo(rownum) foo from dual connect by level <= 10")

获取站点设置为与批量大小相同,您将获得相应的行为。