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

SQL Oracle Discussion :

Insert multiple dans une table


Sujet :

SQL Oracle

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2008
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 5
    Par défaut Insert multiple dans une table
    Bonjour
    Je cherche à faire une insertion de plusieurs lignes avec plusieurs valeurs dans une table.
    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO lien (nodoc, noelement, tcdebut, tcfin, DUREE_ELMT_DOC, nomateriel, ts, date_crea, code_utilisateur, temoin_activite, code_couleur) VALUES (
    ('0177251052', 1, to_number('13411100'), to_number('14054300'), to_number('2432'),'FPVDA95112501', to_date('23/11/10','dd/mm/yy'), to_date('23/11/10','dd/mm/yy'), 'CPT', 'O', 'C'), 
    ('0177251068', 1, to_number('19590400'), to_number('20312900'), to_number('3225'),'FPVDA95112502', to_date('23/11/10','dd/mm/yy'), to_date('23/11/10','dd/mm/yy'), 'CPT', 'O', 'C')
    );
    L'envoi de la requête provoque une erreur me signalant une parenthèse à droite qui manque alors qu'elles sont toutes présentes.
    Cette syntaxe supporte-t-elle les fonctions (style to_number) ? Les tutoriels n'utilisent que des valeurs littérales.
    Avez-vous des pistes de réflexion ?
    Par avance, merci de votre aide.
    Hervé

  2. #2
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    C'est un INSERT ALL que vous cherchez à faire ?
    http://techonthenet.com/oracle/quest...nsert_rows.php

  3. #3
    Membre à l'essai
    Inscrit en
    Janvier 2008
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 5
    Par défaut
    Citation Envoyé par nuke_y Voir le message
    C'est un INSERT ALL que vous cherchez à faire ?
    http://techonthenet.com/oracle/quest...nsert_rows.php
    Bonjour

    J'ai omis de signaler que je travaille avec Oracle 9.

    La table "lien" que je cherche à modifier contient plus de champs (35) que le nombre de champs de la reqête (11). Je ne fournis que les champs dont la valeur doit être non nulle, et ceux dont j'ai besoin pour travailler.

    Si la commande INSERT ALL indique que tous les champs de la table doivent être complétés, ce n'est pas ce que je cherche à faire.
    Cela veut-il dire que la syntaxe de la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO table (col1, col3, col5)
    VALUES (
    (val1_1, val1_2, val1_3),
    (val2_1, val2_2, val2_3) );
    est incorrecte ?
    Les valeurs à insérer doivent-elles être obligatoirement littérales, ou peuvent-elles le résultat de fonctions (style to_number ou to_date) ?

    Une solution pourrait être de compléter le requête avec les champs manquants à "null" dans une requête INSERT ALL.
    A défaut d'élégance, cela pourrait être efficace.

    Merci par avance de votre aide.
    Hervé

  4. #4
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Il me semble que INSERT ALL existe en 9i.

    Tu n'as pas à remplir tous les champs, au contraire, c'est une commande qui sert à l'origine à remplir plusieurs tables différentes en 1 seul ordre INSERT. Par exemple si j'ai une table MA_TABLE(ID, THEVALUE, COMMENTS):
    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
    SQL> create table MA_TABLE (ID NUMBER, THEVALUE VARCHAR2(10), COMMENTS VARCHAR2(100));
     
    Table créée.
     
    SQL> INSERT ALL
      2    INTO MA_TABLE (ID, THEVALUE) VALUES (to_number('1'), substr('b222',2))
      3    INTO MA_TABLE (ID, THEVALUE, COMMENTS) VALUES (2, 'b', 'e')
      4    INTO MA_TABLE (ID, THEVALUE) VALUES (3, 'b')
      5    SELECT * FROM dual;
     
    3 ligne(s) créée(s).
     
    SQL> select * from MA_TABLE;
     
            ID THEVALUE   COMMENTS
    ---------- ---------- ----------------------------------------------------------------
             1 222
             2 b          e
             3 b
    Maintenant je t'avoue que je ne comprends pas pourquoi tu ne veux pas faire plusieurs ordres INSERT au lieu d'en faire 1 multiple.

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Votre syntaxe n'est pas bonne.
    INSERT INTO TABLE VALUES (...) ne sert à insérer qu'une seule ligne.

    En aparté :
    1. to_number('5456') est complètement inutile, écrivez directement 5456.
    2. to_date avec une année codée sur deux chiffres, le jour où un développeur me fait ça je le fais fouetter sur la place publique. Voir bogue de l'an 2000.
    3. tcdebut, tcfin sont des heures de début et de fin : ces colonnes devraient être des dates et non des nombres.


    Donc soit vous construisez une requête depuis DUAL, soit vous répétez votre commande INSERT autant de fois que nécessaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO lien (nodoc, noelement, tcdebut, tcfin, DUREE_ELMT_DOC, nomateriel, ts, date_crea, code_utilisateur, temoin_activite, code_couleur) VALUES
    ('0177251052', 1, 13411100, 14054300, 2432, 'FPVDA95112501', to_date('23/11/2010','dd/mm/yyyy'), to_date('23/11/2010','dd/mm/yyyy'), 'CPT', 'O', 'C');
    INSERT INTO lien (nodoc, noelement, tcdebut, tcfin, DUREE_ELMT_DOC, nomateriel, ts, date_crea, code_utilisateur, temoin_activite, code_couleur) VALUES
    ('0177251068', 1, 19590400, 20312900, 3225, 'FPVDA95112502', to_date('23/11/2010','dd/mm/yyyy'), to_date('23/11/2010','dd/mm/yyyy'), 'CPT', 'O', 'C');
    Ou (notez l'absence du mot VALUES ici) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT INTO lien (nodoc, noelement, tcdebut, tcfin, DUREE_ELMT_DOC, nomateriel, ts, date_crea, code_utilisateur, temoin_activite, code_couleur)
    SELECT '0177251052', 1, 13411100, 14054300, 2432,'FPVDA95112501', to_date('23/11/2010','dd/mm/yyyy'), to_date('23/11/2010','dd/mm/yyyy'), 'CPT', 'O', 'C') FROM DUAL UNION ALL
    SELECT '0177251068', 1, 19590400, 20312900, 3225,'FPVDA95112502', to_date('23/11/2010','dd/mm/yyyy'), to_date('23/11/2010','dd/mm/yyyy'), 'CPT', 'O', 'C') FROM DUAL;

  6. #6
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Bien vu l'UNION de requêtes unitaires sur DUAL

    J'ai toujours pas compris pourquoi il voulait faire ça mais c'est plus propre que de détourner l'INSERT ALL.

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    D'autres SGBD (SQL-Server 2008 au moins) permettent la syntaxe proposée initialement (à quelques parenthèses près).

  8. #8
    Membre à l'essai
    Inscrit en
    Janvier 2008
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 5
    Par défaut
    Citation Envoyé par Waldar Voir le message
    D'autres SGBD (SQL-Server 2008 au moins) permettent la syntaxe proposée initialement (à quelques parenthèses près).
    Tout d'abord, merci pour vos remarques éclairées.

    Je note la syntaxe que vous proposez plus haut.

    Et pour la date, je veux bien "mea culper".

    Bon courage à tous
    Hervé

  9. #9
    Membre Expert
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Par défaut
    Sinon, un truc simple quand on fait des milliers d'insert avec des variables non bindées est de se servir du paramètre session "CURSOR_SHARING"

    Avant la série d'insert, mettre dans la connexion:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    alter session set cursor_sharing = FORCE
    Le but est justement de demander à oracle de faire un pré-traitement pour extraire les constantes et en faire des variable bind.

    J'ai déjà vu des temps divisés par 3 rien qu'avec ça... donc ça ne mange pas de pain d'essayer.

  10. #10
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par remi4444 Voir le message
    Sinon, un truc simple quand on fait des milliers d'insert avec des variables non bindées est de se servir du paramètre session "CURSOR_SHARING"

    Avant la série d'insert, mettre dans la connexion:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    alter session set cursor_sharing = FORCE
    Le but est justement de demander à oracle de faire un pré-traitement pour extraire les constantes et en faire des variable bind.

    J'ai déjà vu des temps divisés par 3 rien qu'avec ça... donc ça ne mange pas de pain d'essayer.
    La solution consiste d'écrire correctement les requêtes pour utiliser le binding. Pour optimiser les N insert il y a le traitement par lot (array processing ou bulk insert ou ...)

  11. #11
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Merci de marquer la discussion en résolu.

  12. #12
    Membre Expert
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Par défaut
    Citation Envoyé par mnitu Voir le message
    La solution consiste d'écrire correctement les requêtes pour utiliser le binding[...]
    Je t'invite à faire cette remarque au moment où, en plein traitement de prod, tu as tous les chefs derriere ton dos la sueur au front tellement ils stressent...

    Plus sérieusement, je suis d'accord avec toi, la solution idéale est de faire les chose bien, bien écrites, bien bindées, bien prévues pour le traitement par lot etc...

    Je donnais juste un simple petit renseignement, un simple petit paramètre à tester qui d'expérience, peu répondre ponctuellement à un problème pour un cout très minime.

    Après, à chacun de prendre ses responsabilités en fonction de ses contraintes...

Discussions similaires

  1. Insertion multiple dans une table et limitation du nombre de lignes
    Par marcandre dans le forum Développement
    Réponses: 1
    Dernier message: 29/04/2011, 15h10
  2. Insertion Multiple dans une Table
    Par faressam dans le forum VBA Access
    Réponses: 2
    Dernier message: 30/09/2008, 14h10
  3. insertion multiple dans une table
    Par nenekes dans le forum Langage SQL
    Réponses: 7
    Dernier message: 22/02/2007, 10h50
  4. [JSP]probleme d'insertion float dans une table
    Par karamazov994 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 14/04/2005, 11h49
  5. Insertion valeure dans une table
    Par krfa1 dans le forum Langage SQL
    Réponses: 6
    Dernier message: 29/03/2005, 10h50

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