MySQL在异常开始之前

时间:2013-01-18 19:57:00

标签: java mysql jdbc

我收到一条错误,指出在开始结果集之前我遇到了异常。我正在尝试获取一个值(来自MySQL数据库的分数),并根据玩家分数将其添加到Java排名。这是为了创建一个记分板。

因此,如果玩家的分数低于当前分数,则会以等级1发布。如果该分数更高,则程序会根据MySQL数据库中的下一个条目检查分数。我还没有实现一个功能来改变所有当前条目的等级增加1。

结论:我正在使用MySQL和Java创建记分板。 Java程序根据输入创建一个分数条目,然后将其发送到MySQL数据库。

      System.out.println("Your score is: "+score*2+"  (A lower score is better.)");
      try {
   // create a java mysql database connection
   String myDriver = "com.mysql.jdbc.Driver";
   String myUrl = "jdbc:mysql://4.30.110.246:3306/apesbridge2013";
   String dbName = "apesbridge2013";
   String tbName = period + "period";
   Class.forName(myDriver);
   Connection conn = DriverManager.getConnection(myUrl, "user", CENSORED);
   next = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
   ResultSet resultSet = next.executeQuery("SELECT * FROM " + tbName);
   int cscore = resultSet.getInt("score");
   for(int sscore = score; sscore > cscore;){
       resultSet.next();
       cscore = resultSet.getInt("score");
       rank++;
   }

   stmt = conn.createStatement();
   stmt.executeUpdate("insert into " + dbName + "." + tbName + " " + "values(" + rank + ", '" + name + "', " + score + ")");
   stmt.close();
   conn.close();
 }
 catch (Exception e)
 {
   System.err.println("Got an exception! ");
   System.err.println(e.getMessage());
 }

    }

3 个答案:

答案 0 :(得分:2)

resultSet.next();放在executeQuery行的正下方。

答案 1 :(得分:2)

如@ hd1所述,您需要在致电ResultSet.next()后致电executeQuery

while (resultSet.next()) {
...

此外,最好使用PreparedStatement代替java.sql.Statement并使用参数占位符来防范SQL Injection攻击:

答案 2 :(得分:1)

你的for循环有问题;退出条件应该是没有更多行要获取。您的查询不保证将满足退出条件,并且您可能尝试获取结果集的结尾。 (甚至当你的for循环确实被输入时,以及如果for循环确实被退出时,该循环导出的秩值是非确定性的,它取决于数据库返回行的顺序。

我也没有看到对resultSet.close()或next.close()的任何调用。

这里有很多问题,很难知道从哪里开始。


但首先,让数据库通过查询返回排名会更有效:

"SELECT COUNT(1) AS rank FROM " + tbName + " WHERE score < " + score 

而不是将所有行拉回来,并比较每个分数。这只是痛苦的,而且很多代码只是噪音。这将使您能够专注于需要在那里的代码。

一旦你开始工作,你需要确保你的语句不容易受到SQL注入的影响,并且带有绑定变量的预处理语句真的是去那里的方法。

并且您确实需要确保对结果集,预准备语句和连接上的close()方法进行调用。我们通常希望这些在最后一个块中。使用嵌套的try / catch块,其中变量立即初始化,如下所示:

try {
    Connection conn = DriverManager.getConnection(...

    try {
        stmt = conn.CreateStatement();

        String query = "SELECT COUNT(1) AS `rank` FROM " + tbName + " WHERE `score` < " + score ;

        try {
            ResultSet rs = stmt.executeQuery(query);
            while (rs.next()) {
               rank = rs.getInt("rank");
            }
        } finally {
            if (rs!=null) { rs.close() };
        }
    } finally {
        if (stmt!=null) { stmt.close() };
    }
} finally {
  if (conn!=null) { conn.close() };
}

或者一个大的try / catch块也可以使用:

} finally {
   if (resultSet!=null) { resultSet.close() };
   if (next!=null) { next.close() };
   if (conn!=null) { conn.close() };
)

重点是,确实需要调用close方法。