3

我正在使用 SQLite 和 JDBC,并收到关于 result_set 为 TYPE_FORWARD_ONLY 的错误。

    PreparedStatement get_mileage = conn.prepareStatement("SELECT * FROM workout_log");
    ResultSet mileage_count = get_mileage.executeQuery();

    mileage_count.absolute(week_start);

    for (int i=week_start;i<=week_finish;i++){
        total_mileage+=mileage_count.getInt(1);
        mileage_count.next();
    }

absolute()尽管我知道它根本没有倒退,但该错误仍在调用中。我尝试添加标志,prepareStatement但它说我的 SQLite 版本不支持ResultSet不是 FORWARD_ONLY。

我的问题是为什么会发生这种情况,即使我没有后退?

4

1 回答 1

4

ATYPE_FORWARD_ONLY ResultSet仅支持next()导航,不支持first(), last(), absolute(int),等方法relative(int)。JDBC 规范明确定义了SQLException在 a 上调​​用 if时抛出的那些TYPE_FORWARD_ONLY

的Javadoc ResultSet.absolute(int)

抛出:
SQLException - 如果发生数据库访问错误;此方法在关闭的结果集上调用或结果集类型为TYPE_FORWARD_ONLY

使用这些方法对 a 没有多大意义TYPE_FORWARD_ONLY:这种类型的结果集不适用于行的“随机访问”,就像可滚动的结果集一样。

例如TYPE_FORWARD_ONLY

  • 只有当您位于第一行之前(以及第一行本身)时,调用first()才会起作用,所以为什么不直接使用next()
  • 仅当您传递比当前行高的行时调用absolute(int)才会起作用,并且您永远无法返回到较早的行
  • relative(int)仅当您传递一个正值并且您永远无法返回到较早的行时,调用才会起作用
  • 调用last()将使您跳过结果集的其余部分,并且您永远无法返回到较早的行

诚然:它可能有它的用途,但它会使驱动程序不必要地复杂化,因为存在的额外约束TYPE_FORWARD_ONLY

如果您想要随机访问,您需要通过指定其中一种可滚动性类型TYPE_SCROLL_INSENSITIVETYPE_SCROLL_SENSITIVE. 如果您的驱动程序不支持这些类型,那么您可能需要使用例如CachedRowSet(特别是com.sun.rowset.CachedRowSetImpl)来模拟它,或者首先加载整个 ResultSet(例如放入 a 中List<? extends List<Object>>)。

于 2013-05-11T07:14:33.620 回答