【问题标题】:ResultSet exception - before start [duplicate]ResultSet 异常 - 开始之前 [重复]
【发布时间】:2020-06-15 14:21:23
【问题描述】:
    public static User getUser (User user) throws Exception {
            String sql = "SELECT * FROM login WHERE userID = '" + user.getuserID() + "'";
            //is FROM Correct?
            PreparedStatement pStatement = conn.prepareStatement(sql);
            ResultSet Rset = pStatement.executeQuery(sql);
            Rset.beforeFirst();
            Rset.next();

            int userID = Rset.getInt("userID");
            String email = Rset.getString("email");
            User userReturn = new User (userID, email);
            return userReturn;
        }

Trace: java.sql.SQLException: Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY.
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.result.ResultSetImpl.beforeFirst(ResultSetImpl.java:426)
    at DaoLayer.daoImplementation.getUser(daoImplementation.java:28)
    at DaoLayer.DaoTest.testGetUser(DaoTest.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)

【问题讨论】:

  • 我不确定是否存在 问题,除了隐含的“为什么会出现此错误”。
  • 你为什么还要打电话给beforeFirst()?这样做在您的代码中毫无意义。

标签: java jdbc singlestore


【解决方案1】:

嗯,你的 JDBC / SQL 可以使用一些更新。

但首先要做的事情。这就是发生的事情:

    ResultSet Rset = pStatement.executeQuery(sql); //Executes the query
    Rset.beforeFirst(); //Moves the cursor backwards before the first row (!)
    Rset.next(); //Goes to the next row

第二行抛出异常,因为光标是 FORWARD_ONLY。另外:你根本不需要那个电话!

这应该可以解决您的直接问题:

    ResultSet Rset = pStatement.executeQuery(sql);
    if(Rset.next()) {
      int userID = Rset.getInt("userID");
      String email = Rset.getString("email");
      User userReturn = new User (userID, email);
      return userReturn;
    } else {
      //Deal with no user found
    }

现在是一般的东西:

  • 很高兴您正在准备声明。但正如 Bashir 已经指出的那样:如果你去使用作为 Statement 类的成员的 executeQuery(sql),你就会丢弃预编译的语句。
  • 使用 PreparedStatement 时 - 也使用绑定参数。这使您的代码更容易被 SQL 注入和
  • 使用 try-with-resource 确保正确关闭所有内容。寻找连接泄漏或打开的游标很容易避免。

最后你可能会得到这样的结果:

public static User getUser (User user) throws Exception {
    String sql = "SELECT * FROM login WHERE userID = ?;
    try(PreparedStatement pStatement = conn.prepareStatement(sql)) {
      pStatement.setInt(1, user.getuserID());
      try(ResultSet Rset = pStatement.executeQuery()) {  
        if(Rset.next()) {
          int userID = Rset.getInt("userID");
          String email = Rset.getString("email");
          User userReturn = new User (userID, email);
          return userReturn;
        }
      }
    } catch(SQLException e) {
      //Deal with the exception
      e.printStackTrace();
    }
    //Error or no user found
    return null;
}

【讨论】:

    【解决方案2】:

    当您创建标准ResultSet 时,您只能使用rs.next() 方法来迭代结果行。所以rs.beforeFirst()是不允许的。 而且在您的代码中也没有必要。创建ResultSet 时,光标会自动放在第一行之前。所以,只使用if(rs.next()) {...}。当rs.next()第一次调用返回false时,表示ResultSet为空。

    【讨论】:

      【解决方案3】:

      pStatement.executeQuery(sql) 更改为pStatement.executeQuery()

      同样userIDint,所以不需要在查询中使用单引号'(但这不是Exception 的根)

      我建议在Rset.next() 上使用if 语句(增加游标,无需使用beforeFirst()),如果查询不返回任何值,这可能会导致获取值时出现异常。

      使用代码如下

      public static User getUser (User user) throws Exception {
              String sql = "SELECT * FROM login WHERE userID = " + user.getuserID();
              //is FROM Correct?
              PreparedStatement pStatement = conn.prepareStatement(sql);
              ResultSet Rset = pStatement.executeQuery();
              if(Rset.next())
              {
                   int userID = Rset.getInt("userID");
                   String email = Rset.getString("email");
                   User userReturn = new User (userID, email);
                   return userReturn;
              }
              return null;
      
          }
      

      【讨论】:

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