Java SQL:Statement.hasResultSet()?

IT小君   2021-11-15T14:04:06

我的应用程序在一个平台上使用 MySQL,在另一个平台上使用 SQLite,因此存在差异,例如在使用以下查询时DELETE FROM USERS

  • MySQL 上PreparedStatement.getResultSet()将返回null.
  • SQLite 上PreparedStatement.getResultSet()将抛出java.sql.SQLException: no ResultSet available.

这可能是也可能不是 SQLite 实现中的错误(我认为它应该返回null),但我必须以某种方式处理这个问题。

我可以使用 a try { ... } catch (SQLException e) { ... },如果异常消息是"no ResultSet available",只需手动返回 null 。但是,这感觉不是正确的方法。

我可以提出一个 if 来检查正在使用的 JDBC 驱动程序并做出相应的反应,但同样,这不是解决问题的好方法。

我真正想要的是一种方法.hasResultSet(),它返回一个boolean OR一种SELECT, UPDATE, INSERT从已执行的语句中获取 SQL 命令(等)的方法。虽然我在 SQL API 中找不到这两者。

点击广告,支持我们为你提供更好的服务
评论(2)
IT小君

当执行返回未知数量结果的查询时,您需要使用execute(). 此方法返回一个boolean指示结果类型:

  • true: 结果是 ResultSet
  • false : 结果是更新计数

如果结果为true,则使用getResultSet()检索ResultSet,否则getUpdateCount()检索更新计数。如果更新计数是,-1则意味着没有更多结果。请注意,更新计数也将-1是当前结果为 a 时ResultSet知道getResultSet()如果没有更多结果或者结果是更新计数应该返回 null也很好,所以 SQL Lite 抛出异常的行为似乎是错误的。

现在,如果您想检索更多结果,请调用getMoreResults()(或它的兄弟接受int参数)。boolean方法返回值与 的含义相同execute()false不代表没有结果!

如果getMoreResults()返回 false getUpdateCount()返回,则不会有更多结果-1(也记录在 Javadoc 中)

从本质上讲,这意味着如果您想正确处理所有结果,您需要执行以下操作:

PreparedStatement pstmt = connection.prepareStatement(...);
// ...
boolean result = pstmt.execute();
while(true)
    if (result) {
        ResultSet rs = pstmt.getResultSet();
        // Do something with resultset ...
    } else {
        int updateCount = pstmt.getUpdateCount();
        if (updateCount == -1) {
            // no more results
            break;
        }
        // Do something with update count ...
    }
    result = pstmt.getMoreResults();
}
2021-11-15T14:04:07   回复
IT小君

问题是您使用无效的方法执行删除操作。而不是使用getResultSet你应该使用Statement#execute(String)

恕我直言,对于 MySQL,SQLite 实现中的 Exeption 比 null 更有效。因为delete不返回集合而是删除行的标量值。

2021-11-15T14:04:07   回复