错误 ORA-01000: 超出最大打开游标
Posted
技术标签:
【中文标题】错误 ORA-01000: 超出最大打开游标【英文标题】:Error ORA-01000: maximum open cursors exceeded 【发布时间】:2017-02-24 14:26:05 【问题描述】:在 Eclipse 中我收到此错误:**Error ORA-01000: maximum open cursors exceeded 我最终已经在块中关闭了连接,但我不知道为什么我会收到这个错误,这是我的代码 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)
【问题讨论】:
为什么将rs
和ps
设置为null?这将阻止那些在 finally 块中被关闭。而且您尝试关闭ps
而不是ps2
。你认为你什么时候关闭连接 - 因为你没有指向你打开的两个变量? (可能在异常处理程序中除外,具体取决于这些调用的作用。)
Alex 我已经修改了这些行,但我仍然遇到同样的错误!
在回答问题后修改问题不是很有帮助。你仍然没有关闭连接。
我应该最后关闭块中的连接吗?
@salma。我不得不赞扬你试图解决这个问题。很多时候,客户只是简单地将 open_cursors 参数作为“修复”。我相信这个小组中的聪明人会找到你问题的根源。
【参考方案1】:
“我不知道为什么会出现这个错误”
会不会是这个错别字?
if (ps2 != null)
try
ps.close();
catch (Exception exx)
您正在关闭 ps
而不是 ps2
【讨论】:
APC,我修改了它,但我仍然遇到同样的错误! 函数 fichierIndius2.ecrireDossier(dos);和 fichierIndius.ecrireDossier(dos); ?他们与 db 有关系吗?如果是,您可以发布代码吗? 还有cnnOracle.getConnexion().,它有什么作用? 它有一个连接,它是在另一个项目中定义的一个类。【参考方案2】:您正在(或曾经)在 else
中将 rs
和 ps
设置为 null,即当 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 块将不再关闭它们)。
【讨论】:
非常感谢 Alex 的回复,我尝试按照您在我的代码中提到的内容进行操作,但现在我收到错误消息:java.lang.NullPointerException。 我只是忘记用 null 实例化准备好的语句。现在它起作用了。非常感谢!以上是关于错误 ORA-01000: 超出最大打开游标的主要内容,如果未能解决你的问题,请参考以下文章
ORA-01000: 超出最大打开游标 - java 代码失败
jdbc 查询5万条数据出现 ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数
Doctrine + Oracle = 超出最大打开游标 (ORA-01000)
使用 Oracle 的 Spring Boot 应用程序 - ORA-01000:超出最大打开游标 - 负载测试期间发生错误