0

I am using JDBC with mysql-connector-java-6.0.2.jar, and, unless I am doing something wrong, I think DatabaseMetaData.ownDeletesAreVisible and DatabaseMetaData.deletesAreDetected implementations are acting somehow inconsistently between each other.

Here's what the JDBC spec says regarding ownDeletesAreVisible:

"...If the deleted row is removed or replaced by an empty row, the method DatabaseMetaData.ownDeletesAreVisible(int type) will return true. It returns false if the ResultSet object still contains the deleted row, which means that the deletion is not visible as a change to ResultSet objects of the given type..."

And regarding deletesAreDetected:

"...The method deletesAreDetected returns false if a row deleted from the ResultSet object is removed from it and true if the deleted row is replaced by an empty or invalid row..."

I added the outputs as comments:

import static java.sql.ResultSet.CONCUR_UPDATABLE;
import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
import java.sql.*;

public class Deletions {

    public static void main(String[] args) throws SQLException {

        try (Connection conn = DBUtils.getConnection();
                Statement stmt = conn.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_UPDATABLE);
                ResultSet rs = stmt.executeQuery("select * from book")) {

            DatabaseMetaData dbmd = conn.getMetaData();

            //prints false
            System.out.println(dbmd.ownDeletesAreVisible(TYPE_SCROLL_INSENSITIVE));

            // prints false. Controversy?
            System.out.println(dbmd.deletesAreDetected(TYPE_SCROLL_INSENSITIVE)); 

            // Prints everything including foo
            printAll(rs); 


            // deletes foo
            while (rs.next()) {
                String title = rs.getString(2);
                if (title.equalsIgnoreCase("foo")) {
                    rs.deleteRow();
                }
            }

            // Prints everything without foo
            printAll(rs);

        }
    }

        private static void printAll(ResultSet rs) throws SQLException {
            rs.beforeFirst();
            while (rs.next()) {
                System.out.println(rs.getString(2));
            }
            rs.beforeFirst();
        }
}
4

2 に答える 2

0

私の結論:

  • MYSQL の使用:

dbmd.ownDeletesAreVisible(TYPE_SCROLL_INSENSITIVE) RETURNED FALSE: "...ResultSet オブジェクトに削除された行がまだ含まれている場合は false を返します..."

dbmd.deletesAreDetected(TYPE_SCROLL_INSENSITIVE) RETURNED FALSE: "... ResultSet オブジェクトから削除された行が削除された場合、false を返します..."

結果:

ResultSet rs = stmt.executeQuery("select * from book");

printAll(rs); // Prints everything including foo

// deletes foo
while (rs.next()) {
    String title = rs.getString(2);
    if (title.equalsIgnoreCase("foo")) {
        rs.deleteRow();
    }
}

printAll(rs); // Prints everything without foo. Makes no sense.
  • Apache Derby DB の使用:

dbmd.ownDeletesAreVisible(TYPE_SCROLL_INSENSITIVE) RETURNED TRUE: "...削除された行が削除されるか空の行に置き換えられた場合、メソッドは true を返します..."

dbmd.deletesAreDetected(TYPE_SCROLL_INSENSITIVE) RETURNED TRUE: "...削除された行が空または無効な行に置き換えられた場合、メソッドは true を返します..."

結果:

ResultSet rs = stmt.executeQuery("select * from book");

printAll(rs); // Prints everything including foo

// deletes foo
while (rs.next()) {
    String title = rs.getString(2);
    if (title.equalsIgnoreCase("foo")) {
        rs.deleteRow();
    }
}

/* Prints 'null' instead of 'foo' here. Now this makes sense */     
printAll(rs);

結論:

この MySQL 実装は、JDBC 仕様に正しく準拠していませんでした。前述の 2 つの方法は、出力に対して矛盾するだけでなく、互いに矛盾しています。

Apache Derby DB は、JDBC 仕様を適切に実装しています。

于 2016-07-23T23:13:53.887 に答える