【问题标题】:MySQL before start of exception [duplicate]异常开始之前的MySQL [重复]
【发布时间】:2013-01-02 14:54:00
【问题描述】:

我收到一条错误消息,指出我在结果集开始之前遇到了异常。我正在尝试获取一个值(来自 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());
 }

    }

【问题讨论】:

  • 那是什么异常,你能提供给我们吗?
  • 另外,您可以通过计算得分较低的记录数来获得排名。这比在java中与数据库中的所有记录进行比较会更有效
  • @spencer7593 对这个老问题给出了实质性答案,但您既没有回复也没有投票。当您收到帮助时,请考虑以某种形式回复,如果只是为了鼓励我们在这里需要的那种乐于助人的人!

标签: java mysql jdbc


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如@hd1所说,在调用executeQuery之后需要调用ResultSet.next()

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

    另外,最好使用PreparedStatement 而不是java.sql.Statement 并使用参数占位符来防止SQL Injection 攻击:

    【讨论】:

      【解决方案3】:

      你的 for 循环有问题;退出条件应该是当没有更多的行可以获取时。您的查询不能保证永远满足退出条件,您可能会尝试获取超过结果集的末尾。 (即使您的 for 循环确实进入了,并且当 for 循环确实退出时,该循环派生的排名值是不确定的,它取决于数据库返回行的顺序。

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

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


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

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

      而不是将所有行拉回,然后比较每个分数。这很痛苦,而且一大堆代码只是噪音。这将使您能够专注于确实需要存在的代码。

      一旦你开始工作,你需要确保你的语句不会受到 SQL 注入的攻击,而使用绑定变量的预处理语句确实是实现这一目标的方法。

      您确实需要确保对结果集、准备好的语句和连接上的close() 方法进行调用。我们通常希望这些在 finally 块中。使用嵌套的 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 方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-16
        • 2022-01-18
        • 2018-06-23
        • 1970-01-01
        • 2011-01-08
        • 2015-07-28
        • 2012-02-08
        相关资源
        最近更新 更多