Java 错误ORA-01000:超过最大打开游标数

Java 错误ORA-01000:超过最大打开游标数,java,eclipse,oracle,Java,Eclipse,Oracle,在Eclipse中,我遇到了以下错误:*错误ORA-01000:超过了最大打开游标数 最后,我已经在块中关闭了连接,但我不知道为什么会出现这个错误,这是我的JAVA代码。 请帮帮我 for (DossierAMO dos = null; it.hasNext();) { PreparedStatement ps = null; ResultSet rs = null; PreparedStatement ps2 = nul

在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) {
                    }
            }






        }
“我不知道为什么会出现这个错误”

可能是这个打字错误吗

            if (ps2 != null)
                try {
                    ps.close();
                } catch (Exception exx) {
                }
您正在关闭
ps
而不是
ps2

“我不知道为什么会出现这个错误”

可能是这个打字错误吗

            if (ps2 != null)
                try {
                    ps.close();
                } catch (Exception exx) {
                }
您正在关闭
ps
not
ps2

您正在(或曾经)将
rs
ps
设置为
else
中的null,即
rc.getInt(1)==0
时。这意味着当您到达最后一个块时,这些测试将失败,
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()
只关闭一个连接,那么您也在泄漏。你需要调查它们里面发生了什么

使用一个连接会更正常,因此您有一个名为say
conn
的变量,您可以使用
cnnOracle.getConnexion()
设置该变量,然后将准备好的状态创建为
ps=conn.prepareStatement(…)

您当前似乎正在获取连接,并在循环中重新创建和销毁准备好的语句。在循环之前获得连接并准备语句一次,然后在循环中执行它们,效率会更高。然后在循环完成后关闭准备好的语句和连接(仍然在异常处理程序中,因为这会返回给调用方,而try块的finally块将不再关闭它们)。

您正在(或曾经)将
rs
ps
else
中设置为null,即
rc.getInt(1)时==0
。这意味着当您到达最后一个块时,这些测试将失败,
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()
只关闭一个连接,那么您也在泄漏。你需要调查它们里面发生了什么

使用一个连接会更正常,因此您有一个名为say
conn
的变量,您可以使用
cnnOracle.getConnexion()
设置该变量,然后将准备好的状态创建为
ps=conn.prepareStatement(…)


您当前似乎正在获取连接,并在循环中重新创建和销毁准备好的语句。在循环之前获得连接并准备语句一次,然后在循环中执行它们,效率会更高。然后在循环完成后关闭准备好的语句和连接(仍然在异常处理程序中,因为它返回给调用方,而try块的finally块将不再关闭它们)。

为什么要将
rs
ps
设置为null?这将阻止那些在最后一个街区被关闭。您正在尝试关闭
ps
,而不是
ps2
。由于没有指向打开的两个连接的变量,您认为什么时候关闭了连接?(除了可能在异常处理程序中,这取决于那些调用的作用。)Alex我已经修改了这些行,但仍然得到相同的错误!在回答问题后修改它并没有多大帮助。你仍然没有关闭连接。我是否应该最终关闭街区中的连接?@salma。我不得不赞扬你试图解决这个问题。很多时候,客户只是简单地将open_cursors参数作为一个“修复”。我相信这群聪明人会找到你问题的根源。你为什么要将
rs
ps
设置为空?这将阻止那些在最后一个街区被关闭。您正在尝试关闭
ps
,而不是
ps2
。由于没有指向打开的两个连接的变量,您认为什么时候关闭了连接?(除了可能在异常处理程序中,这取决于那些调用的作用。)Alex我已经修改了这些行,但仍然得到相同的错误!在回答问题后修改它并没有多大帮助。你仍然没有关闭连接。我是否应该最终关闭街区中的连接?@salma。我不得不赞扬你试图解决这个问题。很多时候,客户只是简单地将open_cursors参数作为一个“修复”。我相信这群人中的聪明人会找到你问题的根源。APC,我修改了它,但我仍然得到同样的错误!fichierIndius2.ecriredosiser(dos)的功能是什么;和菲希耶林迪乌斯。电子档案(dos)?他们和db有什么关系吗?如果是,你能发邮件吗