当我们无法更改游标数量时,避免ORA-0100: Maximum open cursors exceeded
的最佳方法是什么?
有没有比下面更好的方式:
Connection connection = DriverManager.getConnection(/* Oracle Driver */);
Statement st = null;
st = connection.createStatement();
for (/* a lot of iteration with counter */) {
st.executeUpdate(insertSql);
if ( counter % 500 == 0) {
st.close();
connection.commit();
st = connection.createStatement();
}
}
哪个方法调用消耗光标:到executeUpdate
或createStatement
?
我认为这是executeUpdate
方法,这就是我制作这个计数器的原因。
对于我工作的Oracle:
select * from v$version;
结果:
BANNER
----------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for 32-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
答案 0 :(得分:4)
您只关闭每个第50个声明......
for (/* a lot of iteration with counter */) {
st = connection.createStatement(); //you create a statement each iteration!
//...
// This whole thing not right here
if ( counter % 50 == 0) {
st.close(); // not right here -- will have 49 open statements by now
connection.commit(); //this too
}
}
您应该使用预准备语句,并批量插入此数据量。
PreparedStatement statement = connection.prepareStatement(insertTableSQL);
for(<the objects you have>) {
//set parameters into insert query
statement.set*.*(1, <paramValue>);
statement.addBatch(); //add it to the batch
}
statement.executeBatch();//execute whole batch
connection.commit();
答案 1 :(得分:2)
您只需要一个语句用于所有操作,因此您可以在循环外创建语句。
Connection connection = DriverManager.getConnection(/* Oracle Driver */);
Statement statement = connection.createStatement();
for (/* a lot of iteration with counter */) {
// do some INSERT, SELECT, UPDATE
}
statement.close();
connection.close();
现在,在循环内部,您可以运行查询,例如:
statement.executeUpdate("query");