JDBC中结果集的“Kludge”[重复]

Posted

技术标签:

【中文标题】JDBC中结果集的“Kludge”[重复]【英文标题】:"Kludge" of a result set in JDBC [duplicate] 【发布时间】:2012-11-20 05:31:23 【问题描述】:

可能重复:rs.last() gives Invalid operation for forward only resultset : last

所以我试图了解结果集光标,但显然光标所在的位置有问题。

我有一个非常小的应用程序,它会自动分配一个新的整数 id,这将是数据库的最后一个条目,因此是最大的整数。我正在尝试像这样进入最后一个条目(rs 是结果集),所以我可以使用它的值:

rs.last

然后将 the_new_id 分配给 rs.getInt(1)...

但是,我得到“仅向前结果集的无效操作:最后一个”sql 异常。

现在我有一个很大的“kludge”来完成这项工作:

  while(rs.next())
       your_new_id = rs.getInt(1);

然后我就这样分配新的 id。 :-\

如何使用 last 更优雅地实现相同的行为?

感谢任何帮助。

【问题讨论】:

它不安全。如果有人在两者之间插入怎么办?你不会得到最新的 大多数数据库都有生成唯一值以用于合成键字段的方法。在 db2 中,我相信你应该使用 a sequence 好点 Hrdik,我已经考虑过了。然而,这是 唯一 将进行插入的地方。所以现在保证不会造成任何问题。 @Lee 对,我确实使用序列来实现增量。 如果您正在使用序列,则应使用getGeneratedKeys() 来获取在INSERT 期间生成的ID。这样可以为您节省大量往返数据库的时间。 【参考方案1】:

默认情况下,结果集是只进的,这意味着您唯一可以更改光标位置的方法是 next()(如果您按 ID 降序排序,这就是您所需要的)。

The javadoc 解释它:

默认的 ResultSet 对象是不可更新的,并且有一个游标 只向前移动。因此,您只能遍历它一次,然后 仅从第一行到最后一行。可以生产 可滚动和/或可更新的 ResultSet 对象。以下 代码片段,其中 con 是一个有效的 Connection 对象,说明 如何制作可滚动且对更新不敏感的结果集 由其他人,这是可更新的。有关其他信息,请参见 ResultSet 字段 选项。

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                                     ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
// rs will be scrollable, will not show changes made by others,
// and will be updatable

【讨论】:

【参考方案2】:

显然,您正在尝试检索由先前的 INSERT 语句生成的 ID。您不应为此使用单独的 SELECT 语句(这不是事务安全的,并且会给数据库带来不必要的负载)。

要检索生成的 ID,请使用以下 JDBC 调用:

String insert = "insert into some_table (... ";
PreparedStatement pstmt = con.prepareStatement(insert, new String[] "ID");
int rowsInserted = pstmt.executeUpdate();
ResultSet idResult = pstmt.getGeneratedKeys();
int newId = -1;
if (rs.next()) 
  newId = rs.getINt(1);

这将检索在 INSERT 期间为 ID 列生成的值。这将比通过SELECT 获取最新 ID 更快,但更重要的是它是交易安全的。

【讨论】:

以上是关于JDBC中结果集的“Kludge”[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Java JDBC结果集的处理

API解读第三篇——处理结果集的核心对象(JDBC)

具有多个结果集的NHibernate存储过程[重复]

对空结果集的非法操作[重复]

jdbc-mysql基础 ResultSetMetaData getColumnCount 得到结果集的列数

spring jdbc中的双向结果集