Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 24/11/2010, 17h24   #1
Invité de passage
 
Inscription : janvier 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 5
Points : 1
Points : 1
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 :
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é
hgibier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2010, 17h30   #2
Membre Expert
 
Avatar de nuke_y
 
Inscription : mai 2004
Messages : 1 812
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 1 812
Points : 1 609
Points : 1 609
C'est un INSERT ALL que vous cherchez à faire ?
http://techonthenet.com/oracle/quest...nsert_rows.php
__________________
Il vaut mieux monopoliser son intelligence sur des bêtises que sa bêtise sur des choses intelligentes.

Mon combat pour les droits des consommateurs face aux abus des grandes marques.
nuke_y est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2010, 10h17   #3
Invité de passage
 
Inscription : janvier 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 5
Points : 1
Points : 1
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 :
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é
hgibier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2010, 10h37   #4
Membre Expert
 
Avatar de nuke_y
 
Inscription : mai 2004
Messages : 1 812
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 1 812
Points : 1 609
Points : 1 609
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 :
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.
__________________
Il vaut mieux monopoliser son intelligence sur des bêtises que sa bêtise sur des choses intelligentes.

Mon combat pour les droits des consommateurs face aux abus des grandes marques.
nuke_y est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2010, 10h40   #5
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 680
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 680
Points : 10 455
Points : 10 455
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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 :
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 :
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;
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Vieux 25/11/2010, 11h00   #6
Membre Expert
 
Avatar de nuke_y
 
Inscription : mai 2004
Messages : 1 812
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 1 812
Points : 1 609
Points : 1 609
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.
__________________
Il vaut mieux monopoliser son intelligence sur des bêtises que sa bêtise sur des choses intelligentes.

Mon combat pour les droits des consommateurs face aux abus des grandes marques.
nuke_y est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2010, 11h09   #7
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 680
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 680
Points : 10 455
Points : 10 455
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
D'autres SGBD (SQL-Server 2008 au moins) permettent la syntaxe proposée initialement (à quelques parenthèses près).
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2010, 17h45   #8
Invité de passage
 
Inscription : janvier 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 5
Points : 1
Points : 1
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é
hgibier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2010, 18h35   #9
Membre Expert
 
Inscription : avril 2006
Messages : 1 024
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 1 024
Points : 1 175
Points : 1 175
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 :
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.
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/11/2010, 19h36   #10
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 307
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 307
Points : 5 796
Points : 5 796
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 :
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 ...)
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/11/2010, 10h25   #11
Membre Expert
 
Avatar de nuke_y
 
Inscription : mai 2004
Messages : 1 812
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 1 812
Points : 1 609
Points : 1 609
Merci de marquer la discussion en résolu.
__________________
Il vaut mieux monopoliser son intelligence sur des bêtises que sa bêtise sur des choses intelligentes.

Mon combat pour les droits des consommateurs face aux abus des grandes marques.
nuke_y est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/11/2010, 10h37   #12
Membre Expert
 
Inscription : avril 2006
Messages : 1 024
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 1 024
Points : 1 175
Points : 1 175
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...
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h55.


 
 
 
 
Partenaires

Hébergement Web