【问题标题】:How do I check for value existence / why is ResultSet closed in SQLite?如何检查值是否存在/为什么 ResultSet 在 SQLite 中关闭?
【发布时间】:2017-06-07 04:52:26
【问题描述】:

设置

我正在为我的服务器数据库使用JDBC SQLite。

我想做什么

我想检查一个值(例如 ID 或 username)是否已存在于表中。

我的代码

PreparedStatement preparedStatement = connection.prepareStatement("select * from " + tableName + " where " + columnName + "=? limit 1");
preparedStatement.setString(1, value);
ResultSet resultSet = preparedStatement.executeQuery();
resultSet.next();
try { // this was just for testing and is dumb because it prints an error every time the value does not exist.
      // my code actually wasn't wrong. I just tested it badly .. 
      // it's replacable with if (resultSet.next())
    resultSet.getString(1);
    System.out.println("check true");
    return true;
} catch (Exception e) {
    e.printStackTrace();
    System.out.println("check false");
    return false;
}

在这里,我想检查我的column(Name) 中的table 中是否已经存在特定的value。

问题

此代码将始终在resultSet.getString(columnName) 处抛出SQLException: "ResultSet closed"。该值是否已存在于表中并不重要。我的查询也可能是错误的,因为我没有得到应该放在select 之后的内容。我曾经在那里有一个1,但每个人都使用* 表示“所有”,但它没有任何改变。我真的没有得到this,因为它对我来说太复杂了,我只是想知道select 之后的论点是做什么的..

方法

我尝试了很多事情并阅读了很多线程,但我遇到的唯一一件事是我需要先调用 resultSet.next() 并且 ResultSet 不会以这种方式抛出 ResultSet closed 异常,但它没有改变任何东西。 如果有更好的方法来检查表中是否已存在值,请告诉我。

可视化

我在这里有一张表(NULL 无关紧要,它们可能是一些随机值),我想检查ggffvgvg 是否存在。

完成 StackTrace

java.sql.SQLException: ResultSet closed
at org.sqlite.core.CoreResultSet.checkOpen(CoreResultSet.java:69)
at org.sqlite.core.CoreResultSet.markCol(CoreResultSet.java:96)
at org.sqlite.jdbc3.JDBC3ResultSet.getString(JDBC3ResultSet.java:436)
at Database.check(Database.java:50)
at ClientHandler.run(ClientHandler.java:72)

【问题讨论】:

  • 您已将列名用单引号括起来,将其转换为字符串文字。
  • 在此之前我得到“column columnName 不存在”异常,即使它确实存在
  • 我总是将 ResultSet.next() 调用包装到 if 中。如果实际上有一个新行被读取,它返回 true。然后才从结果集中读取值
  • 您也可以通过为 getter 提供列号(从 1 开始)来读取值,例如 resultSet.getString(1) -> 因为您只选择 1 列,它始终是正确的列跨度>
  • 只是为了澄清我的最后一条评论:SQLite(除了 MySQL 和类似的)没有服务器,一旦收到插入请求就会写入文件。连接到它的每个程序都必须手动存储更改(java JDBC 会为您执行此操作,除非您关闭了自动提交)。因此,如果您在“客户端”中插入该行,我猜是第 3 方数据库编辑器并且您没有在此处按保存,则数据库文件还没有收到这些更改(因为它们仅在 db 编辑器中是本地的)

标签: java sqlite jdbc resultset


【解决方案1】:

resultSet.next() 返回一个布尔值,告诉您是否有下一条记录。忽略这个返回值就像用火箭发射器射击自己的脚。

因此,如果您要查找的值不在结果集中,(或者因为它确实不在,或者因为您没有正确要求它,)resultSet.next() 将返回false,您的代码将炸毁,但收到的异常除外。

您的 resultSet.getString(1) 子句将获取结果集中的第一列(如果有当前行)并将其返回给您假设它实际上是一个字符串。大多数表的第一列通常是整数,或者其他类型的关键数据类型,这意味着它很少是字符串。如果幸运的话,它会被 JDBC 驱动程序转换为字符串,但假设你是在诱惑你的命运。

如果您只想检查单个列的值,那么您的查询语句必须只选择该列。这意味着,而不是

"select * from " + tableName + " where " + columnName + "=? limit 1"

你必须这样做

"select " + columnName + " from " + tableName + " where " + columnName + "=? limit 1"

但是,如果我正确理解您要实现的目标,您甚至不需要获取该字段并检查其值。只需 resultSet.next() 的 true 或 false 结果就足够了。

【讨论】:

  • 是的,我告诉他在 cmets 中也是如此......似乎还有另一个问题(.next() 总是返回 false)
  • 现在可以使用了。我的代码没有任何问题,但我只是测试错了。我刚刚接受了你的回答,因为它是唯一的,我的问题已经解决了。实际上@MichaelRitter 为我解决了这个问题,因为他在评论中指出我可能以错误的方式使用了我的 SQLite 查看器(没有重新启动我的服务器/更新服务器上的数据库)。我只是放了 try catch 代码,因为我想看看是否有错误并获得一些反馈。我知道我可以放 (if (resultSet.net()) 并且放 * 或我的 columnName 也没关系。谢谢队友!
  • @MichaelRitter 如果您想将您的评论变成答案,那么 OP 可能会不接受我的并接受您的。
猜你喜欢
  • 2013-10-06
  • 1970-01-01
  • 2015-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 2022-01-21
相关资源
最近更新 更多