[JAVA] Le contenu de la valeur de retour de executeBatch est différent entre 11g et 12c

Environnement d'exécution

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

Résumé de l'événement

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 contenantStatement.SUCCESS_NO_INFO`.

Conclusion: lisez correctement la documentation

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

Le contenu de la valeur de retour de executeBatch est différent entre 11g et 12c
Le comportement est différent entre new et clear () de ArrayList
Une application qui acquiert la valeur du capteur d'accélération par communication UDP entre C # et Android
Différence entre Java, C # et JavaScript (comment trouver le degré d'obésité)
Quelle est la différence entre SimpleDateFormat et DateTimeFormatter? ??
Résumer les différences entre l'écriture C # et Java
[Ruby] Différence entre les put et les retours, les valeurs de sortie et de retour
Existe-t-il une différence de performances entre Oracle JDK et OpenJDK à la fin de 2017?
Passez un argument à la méthode et recevez le résultat de l'opération comme valeur de retour
La comparaison d'énumération est ==, et equals est bonne [Java]
Quelle est la différence entre System Spec et Feature Spec?
Langage Java du point de vue de Kotlin et C #
[Rails] Quelle est la différence entre la redirection et le rendu?
[JAVA] Quelle est la différence entre interface et abstract? ?? ??
Vérification de la relation entre l'image Docker et le conteneur
Quelle est la différence entre ignorer et en attente? [RSpec]
Comment la valeur suivante de l'objet Time est-elle correcte?
Traitement de branche avec la valeur de retour de RestTemplate et le code d'état de ResponseEntity dans Spring Boot
Et si les résultats de sum et inject (: +) sont différents?
[Rails] Quelle est la différence entre l'installation et la mise à jour du bundle?
Quelle est la différence entre une action et une méthode d'instance?
[Swift] Obtenez le moment où la valeur de textField est modifiée
9 Correspond à la valeur de retour
Pourquoi la largeur de l'élément plein écran est de 100% et la hauteur de 100vh
Android - L'ordre du traitement série et du traitement parallèle d'AsyncTask est-il garanti? ??
Le concept de conception de l'API de date et d'heure de Java est intéressant
[Rails] Parlez de prêter attention à la valeur de retour de l'endroit
Quelle est la différence entre un serveur Web et un serveur d'applications?
[Rails] Lire le RSS du site et renvoyer le contenu au premier plan
[Java] Quelle est la différence entre form, entity et dto? [Haricot]
[Swift] La couleur de NavigationBar est différente (plus claire) de la couleur spécifiée.
[Java] Cela peut être heureux si la valeur de retour de la méthode qui retourne null est facultative <>