【发布时间】:2012-02-03 14:21:27
【问题描述】:
我有一个 oracle stored proc 需要从我的 Java 程序中调用。我曾使用CallableStatement 将参数传递给存储过程。我正在使用 oracle 瘦驱动程序(在 Web 逻辑服务器中针对相关的 jndi 条目进行配置)。这个存储的过程没有任何 OUT 值。这个存储过程接受一个数值,并根据接收到的值在数据库中进行大量更新。
我得到一个连接对象,然后在循环中调用这个存储过程(传递 20 个数字 20 次)。当我直接从 oracle 客户端调用此存储过程时,执行将在 2-3 秒内完成。但是,从我的 java 代码中无法预测该行为。有些电话甚至需要 30-40 秒才能完成。
我尝试使用 PreparedStatement 而不是 CallableStatement 并且可以看到边际性能提升(尽管行为仍然不一致)。
- 鉴于 storedproc 没有任何 OUT 参数,就我而言是否可以使用
PreparedStatement而不是CallableStatement? -
PreparedStatement比CallableStatement有一些性能提升,或者我可能没有正确观察到,有什么原因吗? - 是否有更好的方法来解决此性能问题?
【问题讨论】:
-
你能贴出代码吗?或者,确认您的连接没有在每次迭代中建立(而不是重复使用一个连接),并确认您没有在每次迭代中调用
conn.prepareCall()(而不是只有.setInt()和.execute()在循环)。 -
您不止一次调用您的存储过程,对吗?您是否尝试过使用批量调用? docs.oracle.com/javase/1.3/docs/guide/jdbc/getstart/… 见 7.1.3
-
与其进行 20 次调用,不如尝试一个匿名的 PL/SQL 块(开始...调用 proc...调用 proc...end;)来调用您的存储过程 20次并使用匿名块对数据库进行一次调用。
-
我不允许在程序的 PL/SQL 部分上工作 :-( 正在进行单独的讨论以允许存储的 proc 将数字列表作为输入。对不起,如果我错误地理解了您的建议。
-
可以在 Java 端创建匿名 PL/SQL 块:CallableStatement cs = conn.prepareCall ("begin foo(?); end;");
标签: java oracle stored-procedures jdbc