[JAVA] Der Inhalt des Rückgabewerts von executeBatch unterscheidet sich zwischen 11g und 12c

Ausführungsumgebung

Die wichtigsten Softwareversionen, die beim Schreiben dieses Artikels verwendet werden, sind folgende. Docker und Oracle Official Docker Image werden zum Erstellen der Oracle-Datenbank verwendet.

software version, edition
Oracle Database 11g Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
Oracle Database 12c Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production
ojdbc6.jar (11g JDBC Driver) Oracle 11.2.0.2.0 JDBC 4.0 compiled with JDK6 on Sat_Aug_14_12:18:34_PDT_2010
ojdbc8.jar (12c JDBC Driver) Oracle 12.2.0.1.0 JDBC 4.2 compiled with javac 1.8.0_91 on Tue_Dec_13_06:08:31_PST_2016
javac javac 11.0.4
java openjdk version "11.0.4" 2019-07-16

Ereignisübersicht

Beim Upgrade der Datenbank der Java-Anwendung von Oracle Database 11c auf Oracle Database 12g war der Inhalt des Rückgabewerts (Array vom Typ int) von PreparedStatement :: executeBatch geringfügig anders und die Zeit wurde unendlich geschmolzen. Hinterlassen Sie daher einen Hinweis. Ich werde es verlassen.

Der folgende Quellcode verwendet eine Stapelaktualisierung, um 3 Daten in die Tabelle "USERS" einzufügen. Alle Verbindungsinformationen zur Datenbank werden als Laufzeitargument empfangen.

Main.java


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String url = args[0];
        String user = args[1];
        String password = args[2];

        try (Connection c = DriverManager.getConnection(url, user, password);
             PreparedStatement ps = c.prepareStatement("INSERT INTO USERS (ID, NAME) VALUES(?, ?)")) {
            ps.setInt(1, 1);
            ps.setString(2, "Alice");
            ps.addBatch();

            ps.setInt(1, 2);
            ps.setString(2, "Bob");
            ps.addBatch();

            ps.setInt(1, 3);
            ps.setString(2, "Carol");
            ps.addBatch();

            int[] updateCounts = ps.executeBatch();
            System.out.println(Arrays.toString(updateCounts));
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Nachdem Sie diesen Code kompiliert haben, führen Sie ihn zuerst mit dem auf 11g gerichteten Verbindungsziel aus, ändern Sie dann das Verbindungsziel auf 12c und führen Sie ihn wie folgt aus.

$ java -cp ../lib/ojdbc6.jar:. Main jdbc:oracle:thin:@192.168.99.100:1511:xe user1 password
[-2, -2, -2]
$ java -cp ../lib/ojdbc8.jar:. Main jdbc:oracle:thin:@192.168.99.100:1512/ORCLPDB1 user1 password
[1, 1, 1]

Es wurde bestätigt, dass der Inhalt von "updateCounts", dem Rückgabewert von "PreparedStatement :: executeBatch", zwischen 11g und 12c unterschiedlich ist.

Bei 12c ist der Inhalt klar und die Anzahl der Aktualisierungen wird in einem Array vom Typ int gespeichert. Andererseits gibt 11g executeBatch das Array zurück, dasStatement.SUCCESS_NO_INFO enthält.

Fazit: Lesen Sie die Dokumentation richtig durch

Tatsächlich ist dieser Verhaltensunterschied in der Oracle Database-Dokumentation gut dokumentiert.

Zunächst 11g-Dokument:

Wenn der Anweisungsstapel erfolgreich verarbeitet wird, enthält das vom Aufruf der Anweisung executeBatch zurückgegebene Ganzzahlarray, dh das Array für die Aktualisierungsanzahl, immer ein Element für jede Stapeloperation. Bei der Oracle-Implementierung von Standard-Batch-Updates lauten die Werte der Array-Elemente wie folgt: Bei Stapeln vorkompilierter SQL-Anweisungen ist die Anzahl der Zeilen in der Datenbank nicht bekannt, die von den einzelnen im Stapel enthaltenen Anweisungen betroffen sind. Daher sind alle Array-Elementwerte -2. Gemäß der JDBC 2.0-Spezifikation zeigt ein Wert von -2 an, dass der Vorgang erfolgreich war, die Anzahl der betroffenen Zeilen ist jedoch unbekannt.

Andererseits wird in 12c document klar angegeben, dass sich das Verhalten von 11g unterscheidet.

Ab Oracle Database 12c Release 1 (12.1) wurde die Methode executeBatch verbessert, um ein int-Array mit der gleichen Größe wie die Anzahl der Datensätze im Stapel zurückzugeben. Jedes Element im Rückgabearray ist die Anzahl der Zeilen in der Datenbanktabelle, die vom entsprechenden Datensatz im Stapel betroffen sind.

Ich habe es übrigens nicht ausprobiert, aber Dokumentation der Oracle-Datenbank 18c ) Hat genau den gleichen Wortlaut wie der von 12c oben. Mit anderen Worten, es scheint keinen Unterschied im Verhalten von PreparedStatement :: executeBatch zwischen 12c und 18c zu geben.

Recommended Posts

Der Inhalt des Rückgabewerts von executeBatch unterscheidet sich zwischen 11g und 12c
Das Verhalten unterscheidet sich zwischen new und clear () von ArrayList
Eine Anwendung, die den Wert des Beschleunigungssensors durch UDP-Kommunikation zwischen C # und Android erfasst
Unterschied zwischen Java, C # und JavaScript (wie man den Grad der Fettleibigkeit findet)
Was ist der Unterschied zwischen SimpleDateFormat und DateTimeFormatter? ??
Fassen Sie die Unterschiede zwischen C # - und Java-Schrift zusammen
[Ruby] Unterschied zwischen Puts und Return, Output und Return
Gibt es Ende 2017 einen Leistungsunterschied zwischen Oracle JDK und OpenJDK?
Übergeben Sie ein Argument an die Methode und erhalten Sie das Ergebnis der Operation als Rückgabewert
Der Vergleich von enum ist == und gleich ist gut [Java]
Was ist der Unterschied zwischen Systemspezifikation und Funktionsspezifikation?
Java-Sprache aus der Sicht von Kotlin und C #
[Rails] Was ist der Unterschied zwischen Redirect und Rendering?
[JAVA] Was ist der Unterschied zwischen Schnittstelle und Zusammenfassung? ?? ??
Überprüfung der Beziehung zwischen dem Docker-Image und dem Container
Was ist der Unterschied zwischen Überspringen und Ausstehend? [RSpec]
Wie ist der nächste Wert des Time-Objekts korrekt?
Verzweigungsverarbeitung mit dem Rückgabewert von RestTemplate und dem Statuscode von ResponseEntity in Spring Boot
Was ist, wenn die Ergebnisse von Summe und Injektion (: +) unterschiedlich sind?
[Rails] Was ist der Unterschied zwischen Bundle-Installation und Bundle-Update?
Was ist der Unterschied zwischen einer Aktion und einer Instanzmethode?
[Swift] Ermittelt das Timing, wenn der Wert von textField geändert wird
9 Entspricht dem Rückgabewert
Warum die Breite des Vollbildelements 100% und die Höhe 100vh beträgt
Android - Ist die Reihenfolge der seriellen und parallelen Verarbeitung von AsyncTask garantiert? ??
Das Designkonzept der Datums- und Uhrzeit-API von Java ist interessant
[Rails] Sprechen Sie darüber, wie Sie auf den Rückgabewert von where achten
Was ist der Unterschied zwischen einem Webserver und einem Anwendungsserver?
[Rails] Lesen Sie das RSS der Site und geben Sie den Inhalt an die Vorderseite zurück
[Java] Was ist der Unterschied zwischen Form, Entität und dto? [Bohne]
[Swift] Die Farbe der Navigationsleiste unterscheidet sich (heller) von der angegebenen Farbe.
[Java] Es kann glücklich sein, wenn der Rückgabewert der Methode, die null zurückgibt, Optional <> ist