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.


SommaireLes instructions - StatementLes instructions - Statement Généralités (12)
précédent sommaire suivant
 

L'interface Statement représente une instruction SQL. L'obtention d'une instance de cette interface se fait à partir de la Connection :

Code java : Sélectionner tout
1
2
3
4
5
6
7
try{ 
   Connection connection = ... 
   Statement statement = connection.createStatement(); 
} 
catch(Exception e){ 
   //cf. Comment gérer les erreurs ?  
}
Une deuxième méthode permet de spécifier le type des ResultSet créés avec ce Statement. Voir Quels sont les différents types de ResultSet ? Par exemple :

Code java : Sélectionner tout
1
2
3
Statement statement = connection.createStatement( 
 ResultSet.TYPE_FORWARD_ONLY, 
 ResultSet.CONCUR_READ_ONLY);

Mis à jour le 11 avril 2013 Ioan

L'interface Statement propose une dizaine de méthodes permettant l'exécution d'expressions SQL. On peut les regrouper par catégories :

  • les méthodes execute : méthodes génériques pour n'importe quelle expression SQL ;
  • les méthodes executeQuery : méthodes appropriées à l'exécution d'un SELECT ;
  • les méthodes executeUpdate : méthodes appropriées à l'exécution d'une instruction menant à la modification de la BD (INSERT, UPDATE, DELETE, CREATE, etc.) ;
  • les méthodes executeBatch : voir la partie réservée aux transactions.

Voici quelques exemples :

Code java : Sélectionner tout
1
2
3
4
Statement statement = connection.createStatement(); 
boolean result = statement.execute("SELECT * FROM MATABLE"); 
ResultSet resultSet = statement.executeQuery("SELECT ATTRIBUT1, ATTRIBUT2  FROM MATABLE"); 
int col = statement.executeUpdate("INSERT INTO MATABLE VALUES(15,'bonjour',7.0)");

Mis à jour le 11 avril 2013 Ioan

Le retour d'une méthode execute XXX dépend du type de celle-ci :

  • execute : un boolean valant true si l'instruction renvoie un ResultSet, false sinon ;
  • executeQuery : unResultSet contenant les résultats (ne retourne jamais null) ;
  • executeUpdate : unint indiquant le nombre de tuples (lignes) modifiés pour un INSERT, UPDATE et DELETE, ou alors 0 pour les instructions ne retournant rien (CREATE par exemple) ;
  • executeBatch : int[]: un tableau d'entiers indiquant le nombre de tuples modifiés pour chaque commande contenue dans le batch. Ce tableau est ordonné selon l'ordre des ajouts au batch.

Mis à jour le 11 avril 2013 Ioan

En règle générale la réponse est oui. En pratique cela dépendra de l'implémentation du Driver. Cela implique plusieurs choses :

  • possibilité d'utiliser des types spécifiques au SGBD ;
  • possibilité d'utiliser des mots réservés au SGBD : Comment obtenir la liste des mots clefs SQL non standard d'un SGBDR ? ;
  • possibilité d'utiliser les extensions procédurales : par exemple PL/SQL pour Oracle, T/SQL pour Sybase, etc. ;
  • possibilité d'appeler des fonctions spécifiques : procédures stockées par exemple. Dans ce dernier cas, il est tout de même conseillé d'utiliser la syntaxe d'échappement.

Mis à jour le 11 avril 2013 Ioan

Dans ce cas de figure, vérifiez :

  • que vous n'avez pas de warning ;
  • que votre requête SQL est correcte, en la lançant directement avec le SGBD ;
  • que vous utilisez la bonne méthode execute : par exemple, un execute ou un executeUpdate pour « INSERT INTO... ».

Mis à jour le 11 avril 2013 Ioan

L'interface Statement fournit pour cela les méthodes setQueryTimeout(int) et getQueryTimeout(). Par exemple :

Code java : Sélectionner tout
1
2
3
4
Statement statement = ... 
System.out.println("timeout par défaut = "+statement.getQueryTimeout()); 
statement.setQueryTimeout(2); 
//le temps exprimé en secondes
Si le temps accordé à la requête est dépassé, une SQLException est levée.

Mis à jour le 11 avril 2013 Ioan

La méthode execute renvoie un boolean indiquant la présence ou non d'un ResultSet. Pour le récupérer, il suffit de faire comme ceci :

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
String url = "url"; 
String login = "log"; 
String password = "pass"; 
Connection connection = null; 
Statement statement = null; 
ResultSet resultSet = null; 
try{ 
  connection = DriverManager.getConnection(url,login,password); 
  statement = connection.createStatement(); 
  boolean rs = statement.execute("SELECT * FROM MaTable"); 
  if(rs){ 
    resultSet = statement.getResultSet(); 
  }else{ 
    System.out.println("Il n'y a pas de ResultSet, peut-être une mise à jour : "); 
    int nbTuples = statement.getUpdateCount(); 
    System.out.println("Nombre de tuples mis à jour = "+nbTuples); 
  } 
} 
catch(SQLException sqle){ 
   //cf. Comment gérer les erreurs ?  
} 
finally{ 
   //cf. Comment bien fermer une connexion ? 
   //cf. Doit-on fermer un Statement ?  
   //cf. Doit-on fermer un ResultSet ?  
}

Mis à jour le 11 avril 2013 Ioan

Il faut utiliser la méthode setMaxRows(int max) de Statement. Par exemple :

Code java : Sélectionner tout
1
2
3
Statement statement = ...; 
System.out.println("max rows : "+statement.getMaxRows()); 
statement.setMaxRows(200);
Les lignes dépassant ce maximum ne sont tout simplement pas retournées.

Une valeur de 0 signifie qu'il n'y a pas de maximum.

Une SQLException est levée s'il y a une erreur durant une exécution ou si max est négatif.

Mis à jour le 11 avril 2013 Ioan

La méthode getMoreResults() permet de vérifier la présence d'autres ResultSet. Par exemple :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Statement statement = ...; 
if (!statement.execute()) { 
    System.out.println("La requête ne renvoie pas de ResultSet"); 
} else {  
    ResultSet premierResultSet = statement.getResultSet(); 
    if (statement.getMoreResults(Statement.KEEP_CURRENT_RESULT)) { 
        ResultSet secondResultSet = statement.getResultSet(); 
  
        // maintenant les deux ResultSet sont ouverts et prêts à être utilisés 
        premierResultSet.next(); 
        secondResultSet.next(); 
        // ... 
    }else{ 
        System.out.println("Il n'y a pas de second ResultSet"); 
    } 
}
Les arguments de la méthode getMoreResults peuvent prendre les valeurs suivantes :

  • Statement.CLOSE_CURRENT_RESULT : le ResultSet courant doit être fermé lors de l'appel à la méthode getMoreResults ;
  • Statement.CLOSE_ALL_RESULTS : tous les ResultSet précédemment ouverts doivent être fermés lors de l'appel à la méthode getMoreResults ;
  • Statement.KEEP_CURRENT_RESULT : Le ResultSet courant ne doit pas être fermé lors de l'appel à la méthode getMoreResults.

L'argument par défaut est Statement.CLOSE_ALL_RESULTS.

Mis à jour le 11 avril 2013 Ioan

Pour récupérer les clefs autogénérées par l'exécution d'une requête, il faut utiliser la méthode execute(String sql, int autoGeneratedKeys)(ou executeUpdate). L'entier autoGeneratedKeys doit prendre la valeur Statement.RETURN_GENERATED_KEYS.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
Statement statement = ... 
String commandeSQL = " ..."; 
statement.executeUpdate(commandeSQL,Statement.RETURN_GENERATED_KEYS); 
//Les clefs autogénérées sont retournées sous forme de ResultSet 
ResultSet clefs = statement.getGeneratedKeys(); 
if(clefs.next()){ 
    System.out.printn("La première clef autogénérée vaut "); 
    System.out.printn(clefs.getObject(1));   
}
On peut aussi limiter les clefs conservées en utilisant executeXXX(String sql, int[] columnIndexes) ou executeXXX(String sql, String[] columnNames). Les arguments représentent les index/noms des colonnes à observer (N.B. Les index commencent à 1). Une SQLException est levée si les index/noms des colonnes sont erronés ou si l'instruction SQL n'est pas de type INSERT, UPDATE ou DELETE.

Mis à jour le 11 avril 2013 Ioan

La syntaxe d'échappement est définie par un bloc de code à l'intérieur de l'instruction SQL. Ce morceau de code est contenu entre des guillemets. Cette syntaxe permet d'indiquer au Driver que le code n'est pas du SQL et doit être traité de manière spécifique.

Code java : Sélectionner tout
String sql = "{motClefs ... parametres}"
Cette syntaxe peut être utilisée pour :

la gestion des caractères spéciaux, dans LIKE, de manière indépendante du SGBD :

Code java : Sélectionner tout
1
2
3
String sql = "SELECT * FROM Annuaire WHERE nom LIKE '%{escape '''}%'"; 
//sélection dans un annuaire des personnes ayant une apostrophe dans leur nom 
ResultSet resultat = statement.executeQuery(sql);
L'appel de fonctions spécifiques ou non au SGBD :

Code java : Sélectionner tout
1
2
3
4
5
String sql = "SELECT {fn curdate()}, {fn user()}"; 
ResultSet resultat = statement.executeQuery(sql); 
resultSet.next(); 
System.out.println("On est le : "+result.getObject(1)); 
System.out.println("L'utilisateur est : "+result.getObject(2));

l'appel de procédures stockées :

Code java : Sélectionner tout
1
2
3
4
5
String sql = "{call maProcedure(?, ?)}"; 
//appel d'une procédure à deux arguments 
  
//Cf. le chapitre sur les procédures stockées 
CallableStatement call = connection.prepareCall(sql);
Le formatage des données temporelles (date, time et timestamp) :

Code java : Sélectionner tout
1
2
3
4
5
6
{d 'yyyy-mm-dd'} 
//format pour DATE 
{t 'hh:mm:ss'} 
//format pour TIME 
{ts 'yyyy-mm-dd hh:mm:ss.f . . .'} 
//format pour TIMESTAMP

Mis à jour le 11 avril 2013 Ioan

Tout comme pour une Connection, même si le Garbage Collector, libérera les ressources allouées au Statement, il est conseillé de le fermer explicitement.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
Connection connection = null; 
Statement statement = null; 
try{ 
  //initialisation de la connexion et du statement 
} 
catch(SQLException sqle){} 
catch(AutreException ae){} 
finally{ 
  if(statement !=null){try{statement.close();}catch(Exception e){e.printStackTrace();}} 
  if(connection !=null){try{connection.close();}catch(Exception e){e.printStackTrace();}} 
}

Mis à jour le 11 avril 2013 Ioan

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 ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les 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 © 2017 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.

 
Responsables bénévoles de la rubrique Java : Mickael Baron - Robin56 -