FAQ JDBCConsultez toutes les FAQ
Nombre d'auteurs : 8, nombre de questions : 162, dernière mise à jour : 3 juin 2015 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.
- Qu'est-ce qu'un CallableStatement ?
- Comment créer un CallableStatement ?
- Comment passer les paramètres à la procédure (IN parameter) ?
- Comment récupérer le résultat d'une procédure stockée (OUT parameter) ?
- Comment spécifier un paramètre de type INOUT ?
- Comment appeler une fonction ?
- Comment savoir qu'un paramètre de retour (OUT) est de type SQL NULL ?
L'interface CallableStatement, qui étend PreparedStatement, permet de faire appel aux procédures stockées et aux fonctions de manière standard pour tous les SGBD. Pour que cet appel soit indépendant du SGBD ciblé, CallableStatement utilise la syntaxe d'échappement (cf. Qu'est-ce que la syntaxe d'échappement ? ).
La principale différence avec les PreparedStatement se situe au niveau des paramètres. Ceux-ci sont toujours définis par des points d'interrogation, mais en plus des paramètres d'entrée (IN), CallableStatement peut avoir des paramètres de sortie (OUT). Ces paramètres définissent le résultat de la procédure. On peut aussi combiner ces deux types (INOUT).
Une instance de CallableStatement s'obtient grâce aux méthodesprepareCall de Connection. Le premier argument de ces méthodes est une chaîne de caractères définissant l'instruction SQL. Cette chaîne de caractères utilise la syntaxe d'échappement et peut avoir deux formes.
Pour les procédures stockées :
Code java : | Sélectionner tout |
1 2 3 4 5 | String sql = "{call nomDeLaProcedure[(?, ?, ...)]}"; //[(?, ?, ...)] sont les éventuels arguments de la procédure //ces arguments peuvent être de type IN, OUT ou INOUT CallableStatement statement = connection.prepareCall(sql); |
Code java : | Sélectionner tout |
1 2 3 4 5 | String sql = "{? = call nomDeLaProcedure[(?, ?, ...)]}"; //le premier ? est le résultat de la procédure //[(?, ?, ...)] sont les éventuels arguments de la procédure CallableStatement statement = connection.prepareCall(sql); |
Code java : | Sélectionner tout |
1 2 3 4 | String sql = "{? = call max(?, ?)}"; CallableStatement statement = connection.prepareCall(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); |
Comme pour les PreparedSatement, le passage des paramètres d'entrée des CallableStatement se fait grâce à l'ensemble des méthodes setXXX. Il est important de connaître les correspondances entre les types SQL et les types java (cf. Tableau de relations ). En plus de l'index, on peut cibler un paramètre grâce à son nom.
Voici un exemple, pour une procédure stockée chargée de retrouver les abonnés d'un annuaire ayant un certain nom. Cette procédure renvoie plusieurs ResultSet.
Le code Java chargé de la créer et de l'appeler :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | //CHARGEMENT DU DRIVER Class.forName("com.mysql.jdbc.Driver"); //CONNECTION AU SGBD String url = "jdbc:mysql://localhost/test"; String user = "user"; String password = "root"; connection = DriverManager.getConnection(url,user,password); //CREATION DE LA PROCEDURE Statement statement = connection.createStatement(); statement.executeUpdate("DROP PROCEDURE IF EXISTS rechercherNom"); statement.executeUpdate( "CREATE PROCEDURE rechercherNom(IN leNom VARCHAR(50))\n" + "BEGIN\n" + " SELECT * FROM Annuaire WHERE nom = leNom;\n" + " SELECT COUNT(*) FROM Annuaire WHERE nom = leNom;\n" + "END\n"); //APPEL DE LA PROCEDURE String sql = "{call rechercherNom(?)}"; CallableStatement call = connection.prepareCall(sql); //passage de la chaîne "ioio" comme valeur du premier paramètre call.setString(1,"ioio"); if(call.execute()){ //récupération des ResultSet ResultSet resultat1 = call.getResultSet(); call.getMoreResults(Statement.KEEP_CURRENT_RESULT); ResultSet resultat2 = call.getResultSet(); //traitement des informations while(resultat1.next()){ for(int i=0;i<resultat1.getMetaData().getColumnCount();i++){ System.out.print(resultat1.getObject(i+1)+", "); } System.out.println(""); } resultat2.next(); System.out.println("Nombre de lignes = "+resultat2.getObject(1)); resultat1.close(); resultat2.close(); } |
Code java : | Sélectionner tout |
1 2 3 4 | call.setString("leNom","ioio"); call.setObject(1,"ioio"); call.setObject(1,"ioio", Types.VARCHAR); call.setObject("leNom","ioio",Types.VARCHAR); |
Pour récupérer les résultats (OUT) d'un CallableStatement, il faut utiliser les méthodes getXXX correspondant au type retourné. Les paramètres OUT doivent être enregistrés comme tels. Voici un exemple récupérant le nombre d'abonnés d'un annuaire.
Le corps de la procédure :
Code sql : | Sélectionner tout |
1 2 3 4 | CREATE PROCEDURE nombreAbonnes(OUT nb INTEGER) BEGIN SELECT COUNT(*) INTO nb FROM Annuaire; END |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | String sql = "{call nombreAbonnes(?)}"; CallableStatement statement = connection.prepareCall(sql); //enregistrement du paramètre de sortie en fonction de son type et de son nom statement.registerOutParameter("nb", java.sql.Types.INTEGER); //enregistrement du paramètre de sortie en fonction de son type et de son index //statement.registerOutParameter(1, java.sql.Types.INTEGER); statement.execute(); //récupération du résultat en fonction de l'index int resultat = statement.getInt(1); //récupération du résultat en fonction du nom du paramètre //int resultat = statement.getInt("nb"); System.out.println("Nombre d'abonnés = "+resultat); |
Pour spécifier un paramètre INOUT, il suffit de combiner registerOutParameter et setXXX. Voici un exemple qui montre la marche à suivre.
Voici le code Java :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Connection connection = ... ; //CREATION DE LA PROCEDURE Statement statement = connection.createStatement(); statement.executeUpdate("DROP PROCEDURE IF EXISTS hello"); statement.executeUpdate( "CREATE PROCEDURE hello(INOUT param VARCHAR(30))\n" + "BEGIN\n" + " SELECT CONCAT('Hello', param, 'avec JDBC !!!') INTO param;\n" + "END\n"); //APPEL DE LA PROCEDURE String sql = "{call hello(?)}"; CallableStatement call = connection.prepareCall(sql); //passage de la valeur du paramètre call.setString(1, " world "); //enregistrement du paramètre en tant que paramètre OUT call.registerOutParameter(1, Types.VARCHAR); //exécution et récupération du résultat call.execute(); System.out.println(call.getString(1)); |
Code java : | Sélectionner tout |
"Hello world avec JDBC !!!"
L'appel d'une fonction grâce aux CallableStatement utilise la syntaxe suivante :
Code java : | Sélectionner tout |
String sql = "{? = call nomDeLaProcedure[(?, ?, ...)]}";
Code java : | Sélectionner tout |
1 2 3 4 5 6 | String sql = "?= call Hello(?)"; CallableStatement statement = connection.prepareCall(sql); statement.registerOutParameter(1,Types.VARCHAR); statement.setString(2,"world"); statement.execute(); System.out.println(statement.getString(1)); |
Cette question a son intérêt, car bien souvent un CallableStatement va renvoyer une valeur par défaut s'il rencontre un type SQL NULL. Ce sera par exemple la chaine vide pour VARCHAR ou 0 pour INTEGER ou NUMERIC. CallableStatement propose donc la méthode wasNull qui renvoie un boolean indiquant si le dernier paramètre de type OUT était NULL. Cette méthode doit être utilisée seulement après l'appel de la méthode get correspondant au paramètre de sortie. Par exemple :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | String sql = "{getUnNombre(?)}"; CallableStatement statement = connection.prepareCall(sql); statement.registerOutParameter(1,Types.INTEGER); statement.execute(); int resultat = statement.getInt(1); if(statement.wasNull()){ System.out.pritnln("Le résultat est de type SQL NULL"); }else{ System.out.println("Le résultat vaut "+resultat); } |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.