【问题标题】:Why won't resultSet.next() advance when there's clearly more data?当有更多数据时,为什么 resultSet.next() 不前进?
【发布时间】:2018-01-13 05:16:35
【问题描述】:

因此,当显然有更多条目要迭代时,我无法理解为什么来自已执行查询的结果集不会继续前进。我有一个名为 all_projects 的表,当我运行此查询时:

SELECT project_title, created_date, isActive FROM all_projects WHERE project_lead='myUser' ORDER BY created_date DESC;

在我的 PSQL shell 中,这是我得到的结果:

列数据类型有:String、Timestamp 和 Boolean。

我正在尝试获取每一行,从中创建一个 Array[String],最终创建一个字符串数组列表 (List[Array[String]])

当我使用 resultSet.next() 对其进行迭代时,它能够检索前两个值,但是当我在获取第一个时间戳值后调用 next 时,它会失败并返回 false。

下面是我的代码 - 充满了许多 println 调试语句,看看会发生什么,堆栈/和打印跟踪将在底部。

 def getAll(userName: String, db: Database): List[Array[String]] = {
    val tablesQuery = s"SELECT project_title, created_date, isActive FROM all_projects WHERE project_lead=? ORDER BY created_date DESC;"
    var returnResult = new ListBuffer[Array[String]]
    db.withConnection { conn =>
      val ps = conn.prepareStatement(tablesQuery)
      ps.setString(1, userName)
      val qryResult = ps.executeQuery()
      val columnCount = qryResult.getMetaData.getColumnCount
      println("RETRIEVED THIS MANY COLUMNS: " + columnCount)
      while (qryResult.next()) {
        println("Achieved next in while loop >>>>>>>>>>>")
        val row = new Array[String](columnCount)
        for (i <- 0 to columnCount - 1) {
          println(s"Inserting into Array($i) from the column index(${i + 1})")
          if (i < 2) {
            println("Tried to get string: ");
            row(i) = qryResult.getString(i + 1)
          } else { // note I also just tried to keep it all as .getString()
            println("Tried to get boolean: ");
            row(i) = qryResult.getBoolean(i+1).toString
          } // retrieve by column index SQL columns start at 1
          println("Row before we move on: " + row.mkString(", "))
          if (i <= columnCount - 2) {
            println("Called next? -> " + qryResult.next())
          }
        }
        returnResult += row
      }
    }
    returnResult.toList
  }

这是生成的打印堆栈,应该没问题,但正如您所见,当光标位于第一个时间戳值上时尝试 next() 时返回 false

THIS MANY COLUMNS: 3
Achieved next in while loop >>>>>>>>>>>
Inserting into Array(0) from the column index(1)
Tried to get string: 
Row before we move on: Wild Elephants of Mexico, null, null
Called next? -> true
Inserting into Array(1) from the column index(2)
Tried to get string: 
Row before we move on: Wild Elephants of Mexico, 2017-08-05 11:00:44.078232, null
Called next? -> false
Inserting into Array(2) from the column index(3)
Tried to get boolean: 
[error] o.j.ResultSetLogger - java.sql.ResultSet.getBoolean: 
throws exception: org.postgresql.util.PSQLException: ResultSet not positioned properly, perhaps you need to call next.
org.postgresql.util.PSQLException: ResultSet not positioned properly, perhaps you need to call next.

这里发生了什么?

【问题讨论】:

  • 宁愿使用Anorm
  • 您在 for 循环中再次调用 qryResult.next(),同时比较 i 的值与 column length 所以在 for 循环中,您移动到结果集中的下一行。所以你错过了行,因为再次调用 qryResult.next()。可能会检查您的逻辑并仅使用一个 qryResult.next()
  • next() 移动到下一个,而不是下一个,你不应该在你的while循环中调用next(),因为它会让你跳过行。您应该已经注意到这一点,因为您的输出显示您打印了 第一行 的标题和 第二行 的时间戳...
  • 哦,天哪。我以为 next() 只是去了下一个值。如中,从左到右穿过单元格。一切都变得更有意义了。
  • Java 有非常详尽的文档。我可以建议实际阅读 Java 的 API 文档,特别是如果事情的行为与您预期的不同。

标签: mysql scala jdbc


【解决方案1】:

您正在调用qryResult.next(),您的意思是处理单行,破坏一切。 (男孩,你是不是让你的生活变得太艰难了。)

ResultSet 将查询结果表示为指向查询结果单行的可移动指针。您一次处理一行,然后调用next()仅当您完全完成该行的处理

让我们让事情变得更简单。 (我只是在网页上写出来,没有时间检查或编译它,所以请原谅我的嘘声。)

def handleRow( qryResult : ResultSet, columnCount : Int ) : Array[String] = {
   (1 to columnCount).map( i => qryResult.getString(i) ).toArray
}

def getAll(userName: String, db: Database): List[Array[String]] = {
  val tablesQuery = s"SELECT project_title, created_date, isActive FROM all_projects WHERE project_lead=? ORDER BY created_date DESC;"
  db.withConnection { conn =>
    val ps = conn.prepareStatement(tablesQuery)
    ps.setString(1, userName)
    val qryResult = ps.executeQuery()
    val columnCount = qryResult.getMetaData.getColumnCount
    println("RETRIEVED THIS MANY COLUMNS: " + columnCount)
    var buffer = new ListBuffer[Array[String]]
    while (qryResult.next()) {
      buffer += handleRow( qryResult, columnCount )
    }
    buffer.toList
  }
}

【讨论】:

  • 糟糕!最初我输入了(1 until columnCount) 应该是(1 to columnCount),这会让你少一栏。对不起!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多