1

既存のJDBCアプリケーションをHSQLDBバージョン2.2.9を使用するように変換しようとしたときに、いくつかの問題が発生しました(現在、コードベースはMySQL、ORACLE、およびSQLServerで正常に実行されますが、組み込みデータベースも適切なオプションのようです)。

一度に1つずつ、個別に質問します(ただし、これらはすべてJDBCResultSet.deleteRow()メソッドに関連しており、HSQLDB 2.0以降でサポートされています)。

rs.next()呼び出した後にfalseを返すのはなぜrs.deleteRow()ですか?

完全な自己完結型のコードサンプルを次に示します(単純なテーブルの作成、サンプルの挿入、最後のテーブルの削除を含む)。

    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()最初の呼び出しの後、falseを返しますrs.deleteRow()

HSQLDBjavadocに情報が見つかりません。誰かアイデアはありますか?

4

3 に答える 3

1

以前にもコメントしたように、これはHSQLDBJDBC実装のバグのように聞こえます。JDBC 4.1仕様(セクション15.2.4.2)は次のように述べています。

メソッドdeleteRowが呼び出された後、カーソルは次の有効な行の前に配置されます。削除された行が最後の行の場合、カーソルは最後の行の後に配置されます。

これは、への呼び出しnext()が返されるはずだったことを意味しますtrueResultSetより多くの行が含まれている場合)。

于 2013-03-02T07:57:50.160 に答える
1

コードでカーソルの保持可能性を指定します。

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

問題は、HSQLDBJDBCドライバーがResultSet.CLOSE_CURSORS_AT_COMMITデフォルト値として使用していることのようです。

于 2013-03-05T11:36:12.230 に答える
0

ほとんどの場合、構成が間違っています。たとえば、クラスパスに古いバージョンのHSQLDBjarがある場合があります。

この出力は現在の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
于 2013-03-03T20:17:24.583 に答える