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 :

JDBC Sqlite insert out of memory


Sujet :

JDBC Java

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2009
    Messages : 9
    Points : 7
    Points
    7
    Par défaut JDBC Sqlite insert out of memory
    Bonjour,

    j'essaie d'insérer dans une table de 96 colonnes, à partir d'une arraylist, un fichier csv parsé.
    Je parcours ici mon arraylist mais lorsque je veux faire mon INSERT j'ai ce message d'erreur :
    "Select Error:java.sql.SQLException: out of memory"

    voici un ex de transaction :
    "INSERT INTO extract VALUES ("1","0","V28C52019001","A","A-UK","VAUK-SYS","","Published","NoDS","na","S","na","0","0","ko","na","ok","ko","ko","","ok","","","","","","","","","","","","","","","","","","","","","","","","","ko","to do","0","0000-00-00","","2009-06-10","","","","","","","","","","","","","00","ok","","","","","","","","","","","","","","","","","","","","","","","10","ko","12","00","ok","","10","ko","11")"

    Un seul enregistrement est dans la base sur 20000...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for(int i=1;i<listMyList.size();i++){
    // 
    statement.executeUpdate("INSERT INTO extract VALUES "+"("+listMyList.get(i)+")");	
    statement.close();
    connection.close();
    }
    Merci pour votre aide

  2. #2
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    bonjour,

    listMyList.get(i), ça te renvoie quoi ? Un object ? Un string ?

    Pourrais tu afficher ta requête avant de l'exécuter pour voir si elle est correcte ?

    ensuite, tu ne devrais pas fermer ton statement et ta connection à chaque fois car les réouvrir coute cher en performance ...

    tu devrais plutôt faire un truc comme ça (c'est l'idée):

    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
    Connection connection = null;
    Statement statement = null;
     
    try {
      // ouverture de la connection
      // creation du statement
     
      for(...) {
         executeUpdate(...)
      }
     
      // attention, si un trop grand nombre d'insert a été fait, le commit est gourmand
      // un commit tout les 1000 lignes c'est déjà pas mal.
      // au pire tu mets un savepoint avant pour pouvoir tout annuler si besoin
      statement.commit();
    } finally {
     
       if(statement != null) statement.close();
       if(connection != null) connection.close();
     
    }
    Enfin, tu devrais utiliser des PreparedStatement (cf la FAQ). Ca évitera lesproblèmes liés aux caractères spéciaux et en plus tu pourras utiliser le mode "batch" qui améliore les performance si tu as de nombreux insertions à faire ...

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2009
    Messages : 9
    Points : 7
    Points
    7
    Par défaut Re
    Merci pour ta réponse

    Mon ArrayList renvoie des Strings
    Effectivement ca plantait parce que je fermais mon statement à chaque boucle...(Je débute )
    Maintenant ça tourne pas à cause du add

    Voici le code modifié :
    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
    31
    32
     
    try {
     
    // mémoriser horaire début traitement
    long longTpsDebut = System.currentTimeMillis();				
    System.out.println("Beginning insertion ...");
     
    connection.setAutoCommit(false);
     
    PreparedStatement add = connection.prepareStatement("INSERT INTO extract VALUES (" +						"?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +				"?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +				"?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +				"?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +				"?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");			
     
    for(int i=1;i<listMyList.size();i++){
    String sql="INSERT INTO extract VALUES "+"("+listMyList.get(i)+")";
    add.executeQuery(sql);
    add.addBatch();
    }
    int [] counts = add.executeBatch();				
    connection.commit();
     
    // fermeture du PreparedStatement
    add.close();
    // close connection
    connection.close();
     
    // Mémoriser horaire fin traitement
    long longTpsFin = System.currentTimeMillis();
    // Afficher temps du traitement
    System.out.println("Insertion done: " + (longTpsFin-longTpsDebut) + " millisecondes");
     
    }catch(Exception e){
    System.out.println("Error:"+e);  
    }

  4. #4
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    Deux choses :

    1/
    en fait dans ta boucle tu fais le addBatch et une fois sortie de la boucle tu fais le executeBatch qui va exécuter tout ce que tu as mis dans le batch ...

    2/ tu na pas dû regarder bien la doc concernant les preparzedStatement ...
    Il faut que tu lui donnes les valeurs à mettre à la place des ?

    avec un exemple bidion ça donne un truc comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    PreparedStatement ps = connection.prepareStatement("SELECT 1 FROM dual WHERE 1=? AND 2=?");
    for(int i=0; i<10; i++){
       ps.setInt(1,i); // je mets la valeur i dans le premier ?
       ps.setInt(2,i); // je mets la valeur i dans le deuxième ?
       ps.addBatch(); // j'ajoute la requete dans le batch
    }
    // j'execute le batch, soit ici 10 requetes à la suite ...
    ps.executeBatch();

    [EDIT] mais bon dans ton cas, ça ne va pas marcher, il faudrait que ton arraylist contiennent la liste des valeurs à mettre à la place des ?, pas une chaine de caractères ...
    Bref, il faut repenser un peu ton truc ...

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2009
    Messages : 9
    Points : 7
    Points
    7
    Par défaut RE
    Pour le preparedStatement, j'ai regardé la doc mais je trouve dommage que l'on ne puisse pas faire un setString avec une chaine complète de tous les champs à insérer.

    Voici le contexte :
    Je parse un fichier csv pour reconstruire une base de donnée sqlite quotidiennement (pas moyen d'avoir les accès directs à la base d'origine).
    Cet extract comporte 96 colonnes.

    J'ai hésité à faire un constructeur pour la base de donnée et ainsi pouvoir construire une ArrayList du type, mais ça fait un paquet de variables et si la base évolue alors faut trouver le champ à modifier et en être averti aussi..
    C'est clair que ça permettrait de respecter la syntaxe du preparedStatement..!

    J'ai donc construit une ArrayList de String pour un jeu d'enregistrements complet, un jeu ressemble à ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    '1','0','V28C52019001','A','A-UK','VAUK-SYS','','Published','NoDS','na','S','na','0','0','ko','na','ok','ko','ko','','ok','','','','','','','','','','','','','','','','','','','','','','','','','ko','to do','0','0000-00-00','','2009-06-11','','','','','','','','','','','','','00','ok','','','','','','','','','','','','','','','','','','','','','','','10','ko','12','00','ok','','10','ko','11'
    J'ai donc évité le preparedStatement et avec le code suivant ça insére mais ça génère un disk I/O error

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    for(int i=1;i<listMyList.size();i++){
    String sql="INSERT INTO extract VALUES "+"("+listMyList.get(i)+")";
    statement.executeUpdate(sql);
    }
     
    statement.close();
    //close connection
    connection.close();
    Merci !

  6. #6
    Membre expérimenté Avatar de Ivelios
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    1 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 031
    Points : 1 540
    Points
    1 540
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    String requete = "INSERT INTO extract VALUES (";
    for(int i=1;i<listMyList.size()-1;i++){
         requete+= listMyList.get(i)+",";
    }
    requete+=listMyList.get(listMyList.size())+" );";
     
    System.out.println(requete)//tu vérifie personnellement si la requete est bonne
     
    statement.executeUpdate(requete);
     
    statement.close();
    //close connection
    connection.close();

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Juin 2009
    Messages : 9
    Points : 7
    Points
    7
    Par défaut RE
    En fait il me fallait ajouter des transactions et maintenant l'insertion se fait en 2s !!

    Voici le code :
    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
     
    public void insertQC1Extract(ArrayList<String> listMyList,String strDbPath){	
    // create a database connection
    Connection connection =getConnection(strDbPath);			
    try {				
    // mémoriser horaire début traitement
    long longTpsDebut = System.currentTimeMillis();			
    System.out.println("Beginning insertion ...");				
    // create statement
    Statement statement=connection.createStatement();
    // Begin Transaction
    statement.executeUpdate("begin transaction");	
    for(int i=1;i<listMyList.size();i++){					
    String sql="INSERT INTO extract VALUES "+"("+listMyList.get(i)+")";
    statement.executeUpdate(sql);
    }
    // End Transaction
    statement.executeUpdate("commit transaction");			
    // close statement
    statement.close();
    //close connection
    connection.close();	
    // Mémoriser horaire fin traitement
    long longTpsFin = System.currentTimeMillis();
    // Afficher temps du traitement
    System.out.println("Insertion done: " + (longTpsFin-longTpsDebut) + " ms");
    }catch(Exception e){
    System.out.println("Error:"+e);
    }
    }
    Merci à vous pour votre aide

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/06/2009, 00h10
  2. [C++] [gcc] out of memory
    Par fxp17 dans le forum GCC
    Réponses: 5
    Dernier message: 06/01/2006, 10h29
  3. [pb mémoire] out of memory d'eclipse
    Par Casp dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 12/05/2005, 16h39
  4. Out of memory
    Par shurato dans le forum ANT
    Réponses: 1
    Dernier message: 10/11/2004, 16h19
  5. [JBuilder 8] Out of memory problem ...
    Par keros dans le forum JBuilder
    Réponses: 2
    Dernier message: 08/09/2003, 19h03

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