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 |
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.
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.