IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JDBC Java Discussion :

Utilisation ResultSet sur une Vue


Sujet :

JDBC Java

  1. #1
    Membre actif
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Juillet 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Juillet 2019
    Messages : 134
    Points : 209
    Points
    209
    Par défaut Utilisation ResultSet sur une Vue
    Bonjour,

    j'utilise la version Java 1.8.0_221 et j'utilise Talend Open Studio for ESB.

    j'ai une Vue sur laquelle je souhaite faire un SELECT * dessus (tout simple pas de condition). Je dois le faire de sorte que si on change de Vue je récupère les données, même si elles n'ont pas la même structure (Nombre de colonne, Nom de colonne).

    J'ai fait ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     int i = 0;
    Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@server:port:base", "user", "password");
    	if (conn != null) 
    	{
    		System.out.println("Connected to the database!");
    	} 
    	else 
    	{
    		System.out.println("Failed to make connection!");
    	}
    	Statement stmt = conn.createStatement();
    	ResultSet rs;
    	rs = stmt.executeQuery("SELECT * FROM maVue");
    	for (int j =0; j<39;){
    		while ( rs.next() ){ 
                    String data = rs.getString(j);
                    System.out.println("Data : "+data);
                    i++;
                    System.out.println("NB :" +i);
            }
            j++;  
        }  
    conn.close();
    J'ai 39 colonnes dans ma vue de test, 897 lignes de données et certaines colonnes sont vides mais je veux quand même récupérer le champs (avec un NULL ou un champs vide "").
    Je rencontre une erreur pour cette ligne : String data = rs.getString(j); ERREUR : java.sql.SQLException: Index de colonne non valide.

    Ne connaissant pas à l'avance le nombre de colonne j'utilise une boucle for pour passer sur toutes les colonnes, cependant mon Int j n'est pas accepté dans le getString().

    Merci pour toute aide que vous me proposerez !

    EDIT : Je souhaite pouvoir enregistrer le résultat (c'est à dire l'ensemble des données de ma vue) dans un arrayList.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut

    1. Tu peux obtenir le nombre de colonnes en faisant :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
       
      try(ResultSet rs = stmt.executeQuery("SELECT * FROM ODS.VW_FACTORY_PROG")) {
       
         int nbColumns = rs.getMetaData().getColumnCount();
       
      }

    2. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      for (int j =0; j<39;){
       
                 /* du code */
              }
              j++;
      Tu fais une boucle infinie sur j, parce j ne s'incrémente pas dans le bloc du for, mais après, donc j reste à 0.

    3. Exceptionnellement, les index de colonnes vont de 1 à n, donc il faut faire :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      for(int j=1&;j<=nbColumns; j++)
    4. Attention l'appel de getString() suppose que le type de la colonne est compatible avec String (un varchar par exemple). Si tu ne connais pas le type tu peux utiliser getObject() à la place.

    5. Tu as inversé les deux boucles, celles sur les colonnes et celle sur les enregistrements dans le ResultSet.

      Donc au final :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      while ( rs.next() ){ 
            i++;
            System.out.println("Ligne : " + i);
            for (int j =1; j<=nbColumns; j++){ 
                      System.out.println("   Colonne "+j+" : "+rs.getObject(j));
            }
      }
      Tu peux connaître le type des colonnes :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
       
      try(ResultSet rs = stmt.executeQuery("SELECT * FROM ODS.VW_FACTORY_PROG")) {
       
         ResultSetMetaData rsmetadata = rs.getMetaData()
       
         int nbColumns = rsmetadata.getColumnCount();
       
         for(int j=1; j<=nbColumns; j++ ) {
       
            System.out.println("Type colonne " + j + " : " + rsmetadata.getColumnType(j) );
       
         }
       
      }
    6. Attention à la libération des ressources par appel de close() : ça devrait être dans dans un bloc finally, ou mieux en utilisant un try-with-resource comme dans mon premier code ci-dessus. Aussi, tu devrait éviter d'ouvrir et fermer une connexion à chaque requête : c'est très coûteux en temps. Utilise une connexion unique ou un pool.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre actif
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Juillet 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Juillet 2019
    Messages : 134
    Points : 209
    Points
    209
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Salut
    Merci pour toutes ces explications !

    Pour la libération des ressources je peux le faire directement sous le logiciel Talend avec des composants tOracleConnection qui ouvre une connection et tOracleClose qui la ferme. Je pense que je passerai pas ces composants pour ouvrir et fermer ma connection.

    J'ai fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    ArrayList<String> ColumnView = new ArrayList<>();
    ArrayList<String> ValueView = new ArrayList<>();
    int a = 0;
    int NbRowView = (Integer)globalMap.get("NbRowView");
    for (int i = 0; i < NbRowView; i++)
    	{
    		ColumnView.add(((ArrayList)globalMap.get("ColumnNameView")).get(i).toString());
    	}
    Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@serveur:port:base", "user", "password");
    	if (conn != null) {
    		System.out.println("Connected to the database!");
    	} 
    	else {
    		System.out.println("Failed to make connection!");
    	}
    	Statement stmt = conn.createStatement();
    	ResultSet rs;
    	rs = stmt.executeQuery("SELECT * FROM maVue");
    	while ( rs.next() ) {
    		for (int j =0; j<39;j++){ 
                    String data = rs.getString(ColumnView.get(j));
                    System.out.println(ColumnView.get(j)+""+data);
                    ValueView.add(data);
                    a++;
                    System.out.println("NB :" + a);
            }  
        }  
    conn.close();
    System.out.println(ValueView);
    J'avais effectivement fait la boucle for puis la boucle while ...
    Exceptionnellement, les index de colonnes vont de 1 à n, donc il faut faire :
    Par contre mes Indexs commencent à 0 si je fait partir j de 1 je perds la première valeur et j'obtiends l'erreur :IndexOutOfBoundsException lorsque ça passe pour la dernière colonne.

    Attention l'appel de getString() suppose que le type de la colonne est compatible avec String (un varchar par exemple). Si tu ne connais pas le type tu peux utiliser getObject() à la place.
    J'obtiens l'erreur Message détaillé: Type mismatch: cannot convert from Object to String lorsque je remplace mon getString() par un getObject(). Ma Vue contient toute sorte de type de données (Char,Varchar2, Date, Int, Number).

    En tout cas merci pour ton aide j'ai pu récupérer toutes les lignes de ma vue dans un arrayList !

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par PandaRasta Voir le message
    Merci pour toutes ces explications !

    Pour la libération des ressources je peux le faire directement sous le logiciel Talend avec des composants tOracleConnection qui ouvre une connection et tOracleClose qui la ferme. Je pense que je passerai pas ces composants pour ouvrir et fermer ma connection.
    Si DriverManager est java.sql.DriverManager, non. Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@serveur:port:base", "user", "password"); ça créé une connexion jdbc standard et conn.close() la ferme. Ce qui se passe sous Talend regarde Talend et pas Java, mais en effet, le temps de connexion est à répartir entre Talend et Java (le premier pour la création des ressources et l'authentification dans Talend, ce qui sont des processus gourmands et le second pour la création des ressources correspondantes dans la JVM). Il vaut mieux toujours maintenir un pool de connexion que des établir et fermer sans arrêt des connexions. C'est encore plus vrai en multi utilisateur (et ça permet également de gérer le nombre max d'utilisateurs dans l'application et non dans le SGBD).


    Citation Envoyé par PandaRasta Voir le message
    Par contre mes Indexs commencent à 0 si je fait partir j de 1 je perds la première valeur et j'obtiends l'erreur :IndexOutOfBoundsException lorsque ça passe pour la dernière colonne.
    Je ne sais pas pour tes indexs peu importe en fait parce que pour ce qui est des arguments des méthodes des classes JDBC, on va de 1 à n inclus, un point c'est tout :
    Citation Envoyé par javadoc
    getString
    String getString(int columnIndex)
    throws SQLException
    Retrieves the value of the designated column in the current row of this ResultSet object as a String in the Java programming language.
    Parameters:
    columnIndex - the first column is 1, the second is 2, ...
    Returns:
    the column value; if the value is SQL NULL, the value returned is null
    Throws:
    SQLException - if the columnIndex is not valid; if a database access error occurs or this method is called on a closed result set
    Si tu obtiens une IndexOutOfBoundsException, c'est probablement lorsque tu accèdes à une colonne dont l'index est supérieur au nombre de colonnes. Si la borne supérieur est 39 exclue et qu'il n'y a que 15 colonnes forcément ça fait une IndexOutOfBoundsException.


    Citation Envoyé par PandaRasta Voir le message
    J'obtiens l'erreur Message détaillé: Type mismatch: cannot convert from Object to String lorsque je remplace mon getString() par un getObject(). Ma Vue contient toute sorte de type de données (Char,Varchar2, Date, Int, Number).
    Oui parce que tu as dû écrire String data = rs.getObject(1);. Or getObject() retourne de l'Object, donc incompatible avec String. Il te faut donc faire Object data = rs.getObject(1). Ensuite tu peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if ( data instanceof String ) {
       String stringData = (String)data;
       System.out.println("C'est du string: " + stringData);
    }
    else if ...
    Ou utiliser getColumnType() de ResultSetMetadata, qui retourne un int (ou getColumnTypeName() qui retourne un Strng). C'est plus facilement utilisable pour distinguer les types puisqu'on peut utiliser un switch, en revanche ce sont les types DB, ce qui n'est pas forcément pratique pour la manipulation des données Java. Après tu peux toujours te faire un petit convertisseur à base d'enum.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre actif
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Juillet 2019
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Juillet 2019
    Messages : 134
    Points : 209
    Points
    209
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Si ...
    Merci pour toutes tes explications ! Je passe en résolu, encore merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de grant sur une vue utilisant un db_link
    Par squallJ dans le forum Administration
    Réponses: 2
    Dernier message: 04/09/2007, 11h33
  2. [Trigger] Comment le réaliser sur une vue ?
    Par mandale dans le forum DB2
    Réponses: 1
    Dernier message: 19/09/2005, 13h43
  3. Comment avoir une référence sur une Vue
    Par Philippe299 dans le forum MFC
    Réponses: 1
    Dernier message: 12/08/2005, 10h03
  4. Temps d'execution d'un select sur une vue
    Par rosewood dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 21/02/2005, 16h06
  5. delete sur une vue: rule
    Par Bouboubou dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 18/05/2004, 18h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo