Les principales versions de logiciel utilisées dans la rédaction de cet article sont les suivantes. Docker et Oracle Official Docker Image sont utilisés pour créer la base de données Oracle.
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 |
Lors de la mise à niveau de la base de données de l'application Java d'Oracle Database 11c vers Oracle Database 12g, le contenu de la valeur de retour (tableau de type int) de PreparedStatement :: executeBatch
était légèrement différent et l'heure était infiniment fondue, alors laissez une note. Je vais le laisser.
Le code source ci-dessous utilise la mise à jour par lots pour insérer 3 données dans la table ʻUTILISATEURS`. Toutes les informations de connexion à la base de données seront reçues en tant qu'argument d'exécution.
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();
}
}
}
Après avoir compilé ce code, exécutez-le d'abord avec la destination de connexion dirigée vers 11g, puis changez la destination de connexion en 12c et exécutez-le comme suit.
$ 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]
Il a été confirmé que le contenu de ʻupdateCounts, qui est la valeur de retour de
PreparedStatement :: executeBatch`, est différent entre 11g et 12c.
Pour 12c, le contenu est clair et le nombre de mises à jour est stocké dans un tableau de type int. D'autre part, 11g de ʻexecute Batch renvoie le tableau contenant
Statement.SUCCESS_NO_INFO`.
En fait, cette différence de comportement est bien documentée dans la documentation d'Oracle Database.
Tout d'abord, document 11g:
Si le lot d'instructions est traité avec succès, le tableau d'entiers renvoyé par l'appel de l'instruction executeBatch, c'est-à-dire le tableau de comptage de mises à jour, contient toujours un élément pour chaque opération par lots. Dans l'implémentation Oracle des mises à jour standard par lots, les valeurs des éléments du tableau sont les suivantes: Pour les lots d'instructions SQL précompilées, nous ne connaissons pas le nombre de lignes de la base de données affectées par les instructions individuelles contenues dans le lot. Par conséquent, toutes les valeurs des éléments du tableau sont -2. Selon la spécification JDBC 2.0, une valeur de -2 indique que l'opération a réussi, mais le nombre de lignes affectées est inconnu.
En revanche, document 12c indique clairement que le comportement est différent de 11g.
À partir d'Oracle Database 12c Release 1 (12.1), la méthode executeBatch a été améliorée pour renvoyer un tableau int de la même taille que le nombre d'enregistrements dans le lot. Chaque élément du tableau de retour correspond au nombre de lignes de la table de base de données affectées par l'enregistrement correspondant dans le lot.
Au fait, je ne l'ai pas vraiment essayé, mais Documentation d'Oracle Database 18c
A exactement le même libellé que celui de 12c ci-dessus. En d'autres termes, il semble qu'il n'y ait aucune différence dans le comportement de PreparedStatement :: executeBatch
entre 12c et 18c.
Recommended Posts