prepareCall()方法错误地放到某个循环体中
原因:上述代码将prepareCall()函数放在了循环体中,而且语句执行完后又不关闭,导致oralce会话打开游标数超过最大上限open_cursors。一般来说,preparedStatement()和prepareCall()函数每调用一次,即打开一个新的游标。
解决方法:将prepareCall()挪到循环体外,即可解决此问题。当然,也可以循环体内每次执行完后,调用cs.close()。但这样的话jvm负担加重,因为cs对象不断被创建抛弃。
CallableStatement的批处理
PreparedStatement的批处理非常简单,网上范例也很多,此处不必赘言。而CallableStatement的批处理很少使用,可能是这样做的性能改善并不像PreparedStatement那么明显。因为CallableStatement是PreparedStatement的子类,所以也继承了executeBatch()方法,具有批次执行的功能。但限制条件也很苛刻:存储过程必须全是in参数,而不能有out或inout参数。即只能调用空参,或参数全为IN的procedure,而不能是function。如果具有out参数,则一旦调用cs.registerOutParameter()方法即报错。
在[1]的7.1.3的范例中,列举了CallableStatement的批处理写法:
疑问:updateCount到底是通过什么方式返回的呢?在文档中,也只是泛泛地提到:"... Further, the stored procedure must return an update count...",因为批处理不能调用function,所以肯定不是通过函数返回值传递,那又通过什么方式呢?是不是通过SQL%ROWCOUNT来传递,试了好像不起作用。
参考
1、jdk1.3联机文档,http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/callablestatement.html