【问题标题】:Why this java SQLException?为什么这个java SQLException?
【发布时间】:2017-03-21 10:52:18
【问题描述】:

我正在尝试使用另外 2 个表来更新一个表。这是程序:

private void getTickersByNames(String fromtable, String totable) {
    try {
        String ticker;
        con = mhjexcel.con;

        sql = "SELECT * FROM APP." + totable;
        Statement stmt2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
        ResultSet rs2 = stmt2.executeQuery(sql);

        rs2.beforeFirst();
        while (rs2.next()) {
            String name = rs2.getString("name");
            sql = "SELECT * FROM APP." + fromtable + " where name = '" + name + "'";
            Statement stmt1 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            ResultSet rs1 = stmt1.executeQuery(sql);
            rs1.first();
            if (rs1.getRow() == 0) {
                out("the name is not in 1st table" + name);
                rs1.close();
                stmt1.close();
                Statement stmt3 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
                fromtable = "tsetmc";
                sql = "SELECT * FROM APP." + fromtable + " where name = '" + name + "'";
                ResultSet rs3 = stmt3.executeQuery(sql);
                rs3.first();
                if (rs3.getRow() == 0) {
                    out("the name is not in second too");
                    rs3.close();
                    stmt3.close();
                    continue;
                } else {
                    ticker = rs3.getString("ticker");
                    rs3.close();
                    stmt3.close();
                    out(ticker);
                    out(rs2.getRow());
                    rs2.absolute(rs2.getRow());
                    rs2.updateString("ticker", ticker);
                    rs2.updateRow();
                    continue;
                }
            } else {
                ticker = rs1.getString("ticker");
                rs1.close();
                stmt1.close();
                rs2.updateString("ticker", ticker);
                rs2.updateRow();
            }
        }
        rs2.close();
        stmt2.close();

    } catch (SQLException ex) {
        Logger.getLogger(Frame_Ticker.class.getName()).log(Level.SEVERE, null, ex);
    }
}

这是一个例外:

严重:空 java.sql.SQLException:游标状态无效 - 没有当前行。 在 org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)

我看了很多...语句未关闭...结果集未关闭... rs2.getRow() 返回 1 ... rs2.updateString() 有效。 .. 但是 rs2.updateRow() 不起作用 ...我不明白...也许我不应该一起使用某些结果集!?

感谢您的帮助。

编辑

我终于找到了答案,并在此页面中提供。

【问题讨论】:

  • 3 个查询循环?无论你尝试做什么 - 你都做错了。
  • 嗨@juergend。为什么错了?禁止使用3个查询吗?
  • @juergend - 我只是在 rs2 上制作循环!不是其他人。
  • 你...不要循环查询。您检索所需的行并遍历 ResultSet。
  • 对于像计时器(立即跟踪)这样的东西,更新像数据库这样昂贵的东西和像Map这样的内存中的东西是没有意义的

标签: java sql exception jdbc


【解决方案1】:

问题出在此处(正如我发现的那样)三个查询语句不能使用 1 个连接,就像我在程序中所做的那样:

con = mhjexcel.con;
Statement stmt2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
Statement stmt1 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
Statement stmt3 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

所以我像下面这样更改它并且它起作用了:

Connection con1 = DriverManager.getConnection("jdbc:derby://localhost:1527/mhjtestdatabase", null, null);
Connection con2 = DriverManager.getConnection("jdbc:derby://localhost:1527/mhjtestdatabase", null, null);
Connection con3 = DriverManager.getConnection("jdbc:derby://localhost:1527/mhjtestdatabase", null, null);
Statement stmt2 = con2.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
Statement stmt1 = con1.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
Statement stmt3 = con3.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

如果您愿意,可以查看整个程序:

private void getTickersByNames(String fromtable, String totable) {
    try {
        String ticker;
        Connection con1 = DriverManager.getConnection("jdbc:derby://localhost:1527/mhjtestdatabase", null, null);
        Connection con2 = DriverManager.getConnection("jdbc:derby://localhost:1527/mhjtestdatabase", null, null);
        Connection con3 = DriverManager.getConnection("jdbc:derby://localhost:1527/mhjtestdatabase", null, null);

        sql = "SELECT * FROM APP." + totable;
        Statement stmt2 = con2.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
        ResultSet rs2 = stmt2.executeQuery(sql);

        rs2.beforeFirst();
        while (rs2.next()) {
            String name = rs2.getString("name");
            sql = "SELECT * FROM APP." + fromtable + " where name = '" + name + "'";
            Statement stmt1 = con1.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            ResultSet rs1 = stmt1.executeQuery(sql);
            rs1.first();
            if (rs1.getRow() == 0) {
                out("the name is not in 1st table" + name);
                rs1.close();
                stmt1.close();
                Statement stmt3 = con3.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
                fromtable = "tsetmc";
                sql = "SELECT * FROM APP." + fromtable + " where name = '" + name + "'";
                ResultSet rs3 = stmt3.executeQuery(sql);
                rs3.first();
                if (rs3.getRow() == 0) {
                    out("the name is not in second too");
                    rs3.close();
                    stmt3.close();
                    continue;
                } else {
                    ticker = rs3.getString("ticker");
                    rs3.close();
                    stmt3.close();
                    rs2.updateString("ticker", ticker);
                    rs2.updateRow();
                    continue;
                }
            } else {
                ticker = rs1.getString("ticker");
                rs1.close();
                stmt1.close();
                rs2.updateString("ticker", ticker);
                rs2.updateRow();
            }
        }
        rs2.close();
        stmt2.close();
    } catch (SQLException ex) {
        Logger.getLogger(Frame_Ticker.class.getName()).log(Level.SEVERE, null, ex);
    }
}

【讨论】:

  • 是的...可能是因为之前创建了结果集!所以阅读时不需要连接......但写作应该有一个新的语句和连接!!!
【解决方案2】:

你有一个Statement stmt3 = con.createStatement() 的连接泄漏,因为没有关闭之前的Statement stmt3,你正在创建一个新的语句对象并分配给stmt3

在将新的statement object 分配给相同的引用变量之前,您应该始终关闭statement 对象,否则,您将失去引用并且无法使用@987654328 @第一个语句对象,导致连接泄漏。

此外,您正在同时打开结果,但最后只关闭一个结果集(最后一个),这是不正确的,您可以查看以下代码:

private void getTickersByNames(String fromtable, String totable) {
        try {
            String ticker;
            con = mhjexcel.con;
            Statement stmt1 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            ResultSet rs1 = stmt1.executeQuery(sql);

            sql = "SELECT * FROM APP." + totable;
            Statement stmt2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            ResultSet rs2 = stmt2.executeQuery(sql);

            Statement stmt3 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            ResultSet rs3 = stmt3.executeQuery(sql);;

            rs2.beforeFirst();
            while (rs2.next()) {
                String name = rs2.getString("name");
                sql = "SELECT * FROM APP." + fromtable + " where name = '" + name + "'";
                try {
                rs1 = stmt1.executeQuery(sql);
                rs1.first();
                if (rs1.getRow() == 0) {
                    out("the name is not in 1st table" + name);

                    fromtable = "tsetmc";
                    sql = "SELECT * FROM APP." + fromtable + " where name = '" + name + "'";
                    rs3 = stmt3.executeQuery(sql);
                    rs3.first();
                    if (rs3.getRow() == 0) {
                        out("the name is not in second too");
                        continue;
                    } else {
                        ticker = rs3.getString("ticker");
                        out(ticker);
                        out(rs2.getRow());
                        rs2.absolute(rs2.getRow());
                        rs2.updateString("ticker", ticker);
                        rs2.updateRow();
                        continue;
                    }
                }
                ticker = rs1.getString("ticker");
                rs2.updateString("ticker", ticker);
                rs2.updateRow();
                } catch(SQLException sql) {
                     Logger.getLogger(Frame_Ticker.class.getName()).log(Level.SEVERE, null, ex);
                } finally {
                    if(rs3 != null) {
                    rs3.close();
                    }
                    if(rs1 != null) {
                    rs1.close();
                    }
                }
            }

            if(rs3 != null) {
                rs3.close();
                }
                if(rs1 != null) {
                rs1.close();
                }

                if(rs2 != null) {
                    rs2.close();
                    }

                if(stmt1 != null) {
                    stmt1.close();
                    }
                if(stmt2 != null) {
                    stmt2.close();
                    }
                if(stmt3 != null) {
                    stmt3.close();
                    }
         } catch (SQLException ex) {
            Logger.getLogger(Frame_Ticker.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

【讨论】:

  • 嗨@javaguy;我没有很好地得到你的答案,但我已经按照你说的做了,没有发生任何事情,
  • 为什么要将 createStatement() 对象两次分配给 stmt3 ?
  • 在将第二个语句对象分配给同一个引用(stmt3)之前,您需要关闭第一个语句对象
  • 那是一个错误...我现在已经删除了它,我只有一个...但是问题仍然存在... :(
  • 嗨@javaguy;问题不在于关闭和打开查询或结果集。为什么?因为我已经通过out(rs2.isclosed()) stmt2.is.... 和其他人对它们进行了测试...(outsystem.out.println)+ 我还用另一种配置更改了程序,我已经将它放在本页的第一篇文章中: 编辑 + 下方评论
猜你喜欢
  • 2016-08-11
  • 2013-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多