HSQLDB从JDBC结果集中删除行

时间:2013-03-01 13:41:00

标签: java jdbc hsqldb

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

我会一次一个地问一个问题(尽管它们都与JDBC ResultSet.deleteRow()方法有关,自HSQLDB 2.0起支持)

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

这是一个完整的自包含代码示例(包括简单的表创建,示例插入和最后删除表):

    int deletedRows=0;
    try{
        Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:mytestdb",
                 "SA", "");
        String createSQL =
                 "create table test (num INTEGER PRIMARY KEY, str VARCHAR(25))";
        Statement createStmt = c.createStatement();
        createStmt.execute(createSQL);
        createStmt.close();
        String ins = "insert into test (num,str) values (?,?)";
        PreparedStatement pStmt = c.prepareStatement(ins);
        for(int i=0; i<100; i++){
            pStmt.setInt(1, i);
            pStmt.setString(2, "String"+i);
            pStmt.execute();
        }
        // there should now be 100 rows in the table
        String select = "SELECT * FROM test";
        PreparedStatement stmt = c.prepareStatement(select, 
                ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
        ResultSet rs = stmt.executeQuery();    
        rs.beforeFirst();
        while(rs.next()){
            int num = rs.getInt("num");
            if((num%7)==0){
                System.out.println("Deleting row:"+num);
                rs.deleteRow();
                deletedRows++;
            }
        }
        Statement dropStmt = c.createStatement();
        dropStmt.execute("drop table test;");
        dropStmt.close();
    } catch (SQLException sqle) {
        System.out.println("Deleted "+deletedRows+
                    " rows before exception: "+sqle.getMessage());
        sqle.printStackTrace();
    }

在MySQL数据库上运行相同的代码时,输​​出显示每7行都被删除:

  

删除行:0

     

删除行:7

     

...

     

删除行:98

在HSQLDB上,输出为:

  

删除行:0

rs.next()在第一次调用rs.deleteRow()后返回false。

我在HSQLDB javadoc中找不到任何信息。有没有人有任何想法?

3 个答案:

答案 0 :(得分:1)

正如我之前评论过的,这听起来像是HSQLDB JDBC实现中的一个错误。 JDBC 4.1规范(第15.2.4.2节)说:

  

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

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

答案 1 :(得分:1)

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

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

问题似乎是HSQLDB JDBC驱动程序使用ResultSet.CLOSE_CURSORS_AT_COMMIT作为默认值。

答案 2 :(得分:0)

最有可能的是,您的配置错误。例如,您的类路径中可能有较旧版本的HSQLDB jar。

我使用当前的SVN代码获得此输出。自2.2.9以来,JDBC代码没有改变。

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