2016-07-05 1 views
0

Ich bin mit JDBC mit mysql-connector-java-6.0.2.jar, und, wenn ich etwas falsch tue, denke ich DatabaseMetaData.ownDeletesAreVisible und DatabaseMetaData.deletesAreDetected Implementierungen handeln irgendwie uneinheitlich untereinander.DatabaseMetaData.ownDeletesAreVisible vs DatabaseMetaData.deletesAreDetected Kontroverse

Hier ist, was die JDBC-Spezifikation sagt in Bezug auf ownDeletesAreVisible.

"... Wenn die gelöschte Zeile entfernt oder durch eine leere Zeile ersetzt, wobei das Verfahren DatabaseMetaData.ownDeletesAreVisible (int-Typ) wird return true Es gibt false, wenn das ResultSet-Objekt noch die gelöschte Zeile enthält, was bedeutet, dass das Löschen zu ResultSet Objekten des angegebenen Typs nicht sichtbar als eine Änderung ist ...

Und deletesAreDetected zu:

.. .Das Meth od deletesAreDetected false zurückgibt, wenn eine Zeile aus dem ResultSet-Objekt gelöscht wird daraus entfernt und dann, wenn die gelöschte Zeile durch eine leere oder ungültige Zeile ersetzt wird ... "

Ich habe die Ausgänge als Kommentare:

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(); 
     } 
} 
+0

Sie sollten Ihre Kommentare wirklich in den Textkörper einfügen, was das Lesen wesentlich erleichtert. –

+0

Vielen Dank für den Hinweis. Erledigt. –

Antwort

0

Mein Fazit:

  • Mit MYSQL:

dbmd.ownDeletesAreVisible (TYPE_SCROLL_INSENSITIVE) FALSCH: “... Es gibt false zurück, wenn das Objekt ResultSet noch die gelöschte Zeile enthält. .. "

dbmd.deletesAreDetected (TYPE_SCROLL_INSENSITIVE) FALSCH: " ... re falsch schaltet, wenn eine Zeile aus dem ResultSet Objekt gelöscht wird daraus entfernt ...“

Ergebnisse:

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. 
  • Verwendung von Apache Derby DB:

dbmd.ownDeletesAreVisible (TYPE_SCROLL_INSENSITIVE) RETURNED TRUE: "... Wenn die gelöschte Zeile entfernt oder durch eine leere Zeile ersetzt wird, gibt die Methode true zurück ..."

dbmd.deletesAreDetected (TYPE_SCROLL_INSENSITIVE) RETURNED TRUE: "... Die Methode true zurück, wenn die gelöschte Zeile durch eine leere oder ungültige Zeile ersetzt wird ..."

Ergebnisse:

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); 

Schlussfolgerung:

Diese MySQL-Implementierung hielt die JDBC-Spezifikation nicht korrekt ein. Die beiden oben genannten Methoden widersprechen sich ebenso wie gegen die Outputs.

Die Apache Derby-DB implementiert die JDBC-Spezifikationen ordnungsgemäß.

0

Es ist kein Widerspruch, die JDBC 4.2 specification, Abschnitt 15.2.4.2 sagt (emphasis ich):

Nach dem Verfahren deleteRow die aktuelle Zeile genannt worden ist, wird in der zugrunde liegenden Datenquelle gelöscht. Dieses Löschen ist als eine Änderung in dem geöffneten ResultSet Objekt sichtbar, wenn die Zeile entweder entfernt oder durch eine leere oder ungültige Zeile ersetzt wird.

Wenn die gelöschte Zeile wird durch eine leere Zeile entfernt oder ersetzt, wobei das Verfahren DatabaseMetaData.ownDeletesAreVisible(int type) wird true zurückzukehren. Es gibt false zurück, wenn das Objekt ResultSet immer noch die gelöschte Zeile enthält, was bedeutet, dass das Löschen nicht als Änderung an ResultSet-Objekten des angegebenen Typs sichtbar ist.

[..]

Wenn ein ResultSet Objekt Deletionen erkennen kann, die ResultSet Methode rowDeleted true zurück, wenn die aktuelle Zeile wird gelöscht und falsch, wenn es nicht hat. rowDeleted gibt jedoch auch false zurück, wenn das ResultSet-Objekt Löschungen nicht erkennen kann. Die Methode DatabaseMetaData.deletesAreDetected(int type) kann aufgerufen werden, um zu sehen, ob ein ResultSet Objekt des angegebenen Typs die Methode rowDeleted aufrufen kann, um eine sichtbare Löschung zu erkennen. Die Methode deletesAreDetected gibt false zurück, wenn eine aus dem Objekt ResultSet gelöschte Zeile daraus entfernt wird, und true, wenn die gelöschte Zeile durch eine leere oder ungültige Zeile ersetzt wird.

Es etwas zu lesen zwischen den Zeilen nimmt (und in diesem Abschnitt am Stück Beispielcode suchen), aber dies bedeutet, dass deletesAreDetectednur Sinn hat, wenn Löschungen sichtbar sind, es erkennt, wie die Löschungen sind sichtbar: Entweder wurde die Zeile gelöscht (false) oder durch eine leere oder ungültige Zeile ersetzt (true).

So wie ownDeletesAreVisiblefalse zurückgibt, hat das Ergebnis deletesAreDetected keine Bedeutung in Bezug auf 'eigene' Löschungen (abgesehen von 'löscht nicht erkannt'); Es kann eine Bedeutung in Bezug auf "andere" Löschungen haben, aber ich bezweifle, dass andere Löschungen sichtbar sind, wenn Ihre eigenen nicht sind.

+0

Ich sehe, was Sie meinen, außer im ersten Teil, wenn es besagt, dass DatabaseMetaData.ownDeletesAreVisible (Int-Typ) false zurückgibt, wenn das ResultSet-Objekt noch die gelöschte Zeile enthält. In meinem Szenario gab es false zurück, was bedeutet, dass resultset es immer noch hatte, ohne irgendetwas zu ersetzen. Warum war die gelöschte Zeile nicht mehr im Resultset, als ich sie erneut ausgedruckt habe? –

+0

Ich hatte sowohl ownDelesAreVisible als auch DeletesAreDetected und gab false zurück. Es heißt "Wenn die gelöschte Zeile entfernt oder durch eine leere Zeile ersetzt wird, gibt die Methode DatabaseMetaData.ownDeletesAreVisible (int-Typ) True zurück." Also wurde meine Zeile nicht entfernt oder ersetzt. Es sagt auch: "Die Methode löschtAreDetected gibt false zurück, wenn eine gelöschte Zeile aus dem ResultSet-Objekt daraus entfernt wird". Warum wurde ich falsch? ownDeletesAreVisible sagte, dass es nicht entfernt wurde. Dies ist die "Kontroverse", um die ich mich bemühe. –

+0

@imacellone dann kann ich nur vorschlagen, dass entweder meine Interpretation falsch ist, oder der Treiber, den Sie verwenden, sein Verhalten in den DatabaseMetaData nicht korrekt angibt. –

Verwandte Themen