在Eclipse中我收到此错误:**错误ORA-01000:超出最大打开游标数 我已经在块中关闭了连接,但我不知道为什么我会收到此错误,这是我的代码JAVA。 请帮帮我!
for (DossierAMO dos = null; it.hasNext();) {
PreparedStatement ps = null;
ResultSet rs = null;
PreparedStatement ps2 = null;
ResultSet rs2 = null;
try {
dos = (DossierAMO) it.next();
//PreparedStatement ps = null;
//ResultSet rs = null;
/*try
*
{*/
System.out.println("Imma"+dos.getImma());
ps = cnnOracle.getConnexion().prepareStatement(
"select count(IMM_IMM_V_NUM_IMM) from d_salaire@prod_dist where SAL_C_DS =21 and IMM_IMM_V_NUM_IMM =?",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY
);
ps.setString(1,dos.getImma());
rs = ps.executeQuery();
if (rs.next()){
if (rs.getInt(1) != 0)
//System.out.println("> Ecriture des dossiers d'indus dans le fichier d'indus2");
fichierIndius2.ecrireDossier(dos);
else
{
ps2 = cnnOracle.getConnexion().prepareStatement(
"select count(DOS_N_NUM_DOS) from d_dossier@prod_dist where IMM_IMM_V_NUM_IMM =?",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY
);
ps2.setString(1,dos.getImma());
rs2 = ps2.executeQuery();
if (rs2.next()){
if (rs2.getInt(1) != 0)
fichierIndius2.ecrireDossier(dos);
else{
fichierIndius.ecrireDossier(dos);
}}}}
} catch (Exception ex) {
requete.fermer();
fichierIndius.fermerSansException();
fichierIndius2.fermerSansException();
cnnAS400.fermerConnexion();
cnnAS400FO.fermerConnexion();
cnnOracle.fermerConnexion();
System.err
.println("Erreur d'écriture dans le fichier d'indus! / EXC : "
+ ex);
return;
}
finally{
if (rs != null)
try {
rs.close();
} catch (Exception exx) {
}
if (rs2 != null)
try {
rs2.close();
} catch (Exception exx) {
}
if (ps != null)
try {
ps.close();
} catch (Exception exx) {
}
if (ps2 != null)
try {
ps2.close();
} catch (Exception exx) {
}
}
}
答案 0 :(得分:2)
"我不知道为什么我会收到这个错误"
这可能是这个错字吗?
if (ps2 != null)
try {
ps.close();
} catch (Exception exx) {
}
您关闭ps
而不是ps2
答案 1 :(得分:1)
您(或曾在)rs
中设置ps
和else
为空,即rc.getInt(1) == 0
时。这样一来,当你到达finally块时,这些测试会失败,ps
和rs
无法关闭:
if (rs != null)
try {
rs.close();
} catch (Exception exx) {
}
....
if (ps != null)
try {
ps.close();
} catch (Exception exx) {
}
正如@APC已经指出的那样,你也在(或者是)在这里关闭了错误的陈述:
if (ps2 != null)
try {
ps.close();
} catch (Exception exx) {
}
更大的问题是您没有按照声明的那样释放您的连接。调用cnnOracle.fermerConnexion()
,但在异常处理程序中仅 :
...
} catch (Exception ex) {
requete.fermer();
fichierIndius.fermerSansException();
fichierIndius2.fermerSansException();
cnnAS400.fermerConnexion();
cnnAS400FO.fermerConnexion();
cnnOracle.fermerConnexion();
System.err
.println("Erreur d'écriture dans le fichier d'indus! / EXC : "
+ ex);
return;
}
finally{
...
在(正确)关闭语句和结果集之后,您还需要关闭finally块中的连接。
您还需要查看cnnOracle.fermerConnexion()
正在做什么。您拨打cnnOracle.getConnexion()
两次,每次准备好一次。如果那些返回不同的连接,并且fermerConnexion()
只关闭一个,那么你也会泄漏。你需要调查每个内部发生的事情。
使用一个连接更为正常,因此您有一个名为conn
的变量,您使用cnnOracle.getConnexion()
进行设置,然后将您准备好的状态创建为ps = conn.prepareStatement(...)
。
您目前似乎正在获取连接并重新创建并销毁循环内的预准备语句。在循环之前获取连接并准备一次语句会更有效,并且只需在循环内执行它们。然后在循环完成后关闭准备好的语句和连接(并且仍然在异常处理程序中,因为它返回到调用者,try块的finally块将不再关闭它们。)