Java HSQLDB从JDBC结果集中删除行

Java HSQLDB从JDBC结果集中删除行,java,jdbc,hsqldb,Java,Jdbc,Hsqldb,我在尝试将现有JDBC应用程序转换为使用HSQLDB2.2.9版时遇到了几个问题(目前代码库在MySQL、ORACLE和SQLServer上成功运行,但嵌入式数据库似乎也是一个不错的选择) 我将一次单独提出一个问题(尽管它们都与自HSQLDB2.0以来支持的JDBCResultSet.deleteRow()方法相关) 为什么调用rs.deleteRow()后,rs.next()返回false 下面是一个完整的自包含代码示例(包括简单的表创建、示例插入和删除末尾的表): int deletedRo

我在尝试将现有JDBC应用程序转换为使用HSQLDB2.2.9版时遇到了几个问题(目前代码库在MySQL、ORACLE和SQLServer上成功运行,但嵌入式数据库似乎也是一个不错的选择)

我将一次单独提出一个问题(尽管它们都与自HSQLDB2.0以来支持的JDBC
ResultSet.deleteRow()
方法相关)

为什么调用
rs.deleteRow()
后,
rs.next()返回false

下面是一个完整的自包含代码示例(包括简单的表创建、示例插入和删除末尾的表):

int deletedRows=0;
试一试{
连接c=DriverManager.getConnection(“jdbc:hsqldb:mem:mytestdb”,
"SA",;
字符串创建SQL=
“创建表测试(num INTEGER主键,str VARCHAR(25))”;
语句createStmt=c.createStatement();
createStmt.execute(createSQL);
createStmt.close();
String ins=“插入测试(num,str)值(?,)”;
准备好的报表pStmt=c.准备好的报表(ins);

对于(int i=0;i,正如我之前所评论的,这听起来像是HSQLDB JDBC实现中的一个bug

调用方法
deleteRow
后,光标将位于下一个有效行之前。如果删除的行是最后一行,光标将位于最后一行之后


这意味着对
next()
的调用应该返回
true
(如果
ResultSet
包含更多行)。

最有可能的是,您有错误的解释。例如,您的类路径中可能有一个较旧版本的HSQLDB jar

我用当前的SVN代码得到这个输出。JDBC代码自2.2.9以来没有改变

Deleting row:0
Deleting row:7
Deleting row:14
Deleting row:21
Deleting row:28
Deleting row:35
Deleting row:42
Deleting row:49
Deleting row:56
Deleting row:63
Deleting row:70
Deleting row:77
Deleting row:84
Deleting row:91
Deleting row:98

在代码中指定光标保持性:

c.prepareStatement(select,
     ResultSet.TYPE_SCROLL_INSENSITIVE,
     ResultSet.CONCUR_UPDATABLE,
     ResultSet.HOLD_CURSORS_OVER_COMMIT);

问题似乎是HSQLDB JDBC驱动程序使用
ResultSet.CLOSE\u CURSORS\u AT\u COMMIT
作为默认值。

顺便说一句,我知道我可以使用简单的SQL delete语句执行相同的删除操作,但这在实际的现有代码中不是一个选项(删除不像示例那么简单,需要特定于DB实现的SQL)。这听起来像是
ResultSet.deleteRow()的HSQLDB实现中的一个bug
。这也是我的想法,但我找不到这样的错误报告。我会再看一次,并询问他们的开发团队。我在2.2.9 jar和2.2.9源代码上运行了它,发现了问题。看起来默认的光标保持能力是
在提交时关闭光标
而不是
在提交时按住光标
。如果
c.prepareStatement(选择,ResultSet.TYPE\u滚动\u不敏感,ResultSet.CONCUR\u可更新,ResultSet.HOLD\u游标\u覆盖提交)
,代码按预期工作。可能至少HSQLDB的JavaDoc中应该有一个not…我认为我们应该在HSQLDB论坛上继续讨论。我将添加我自己的答案并在这里完成。。。
c.prepareStatement(select,
     ResultSet.TYPE_SCROLL_INSENSITIVE,
     ResultSet.CONCUR_UPDATABLE,
     ResultSet.HOLD_CURSORS_OVER_COMMIT);