Insertion multiple

Résolu/Fermé
codeForEver Messages postés 16 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 1 novembre 2011 - 3 janv. 2010 à 17:19
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 - 23 janv. 2010 à 17:02
Bonjour,
Pour insérer une ligne dans une table pas de souci :-) mais pour en insérer plusieurs un pb :-(

J'ai pris comme modèle

Insert into Voiture(Annee,Marque,Modèle,Identifiant)
VALUES (1984,Renault,Fuego,3,
        2000,Renault,Clio2,4,
        2001,Renault,Avensis,5
);


que j'avais trouvé sur http://www.wikituto.org/index.php/Ins%C3%A9rer_des_donn%C3%A9es_SQL

mais j'ai un message d'erreur comme quoi trop de valeurs :-(

qq'un a une idée ?

23 réponses

BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
6 janv. 2010 à 01:48
Bonsoir CodeForEver,
Si je comprends bien, la solution sqlLoader t'intéresserait ... je te guiderai au cours de ma journée de travail (disons à partir de 10h00).

Le but du jeu est le suivant : tu as un fichier texte qui contient les enregistrements que tu veux insérer dans une table. Voici à quoi peut ressembler ton fichier de données :

valeur1Col1;valeur1Col2;valeur1Col3
valeur2Col1;valeur2Col2;valeur2Col3
valeur3Col1;valeur3Col2;valeur3Col3
...
valeurNCol1;valeurNCol2;valeurNCol3

A sqlLoader, tu donneras en paramètre de ta ligne de commande un fichier de contrôle qui indiquera dans quelle table (nom et structure) tu veux insérer ces données.

Ce qui est pas mal dans cette méthode, c'est que :
- l'outil produit un fichier de traces qui t'indiquera pourquoi telle ligne a été rejetée
- les lignes rejetées sont insérées dans un fichier BAD qui a la même structure que ton fichier de données.
Une fois l'erreur corrigée, tu peux alors relancée la commande sqlLoader en donnant en fichier de données
le fichier BAD et du coup, les données auparavant rejetées sont remises dans le circuit ;-)

@ tout'à l'heure pour le tutorial parce que là, je m'emballe !
1
codeForEver Messages postés 16 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 1 novembre 2011
6 janv. 2010 à 21:46
Salut BadGuitarist,

Merci bcp et donc c'est parti !

Pour commencer je prépare le fichier texte, structuré comme ton modèle.

Est-ce que sqlldr.exe doit être lancé ?
J'ai essayé mais une fois cliquer sur celui là, rien ne s'affiche !
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
7 janv. 2010 à 13:14
Quand tu charges des données, en général, on cherche aussi à faire des traitements.

Conseil 1 :
Tu peux faire des contrôles directement avec SQLLOADER en les précisant dans le fichier de contrôle (le fichier .ctl). Mais c'est compliqué car cela oblige à mieux connaître ce puissant outil.
Ce que je fais, pour profiter de mes acquis, c'est que je charge les données dans une table intermédiaire (une table de travail en quelque sorte) sur laquelle je pose un trigger sur insertion (de type BEFORE INSERT EACH ROW).
C'est par le biais de ce trigger, écris en PL/SQL, que je fais tous les contrôles et que je dispatche les informations dans les différentes tables de ma base de données.

Conseil 2 (et Qui va dans le sens du conseil 1) :
je limite le type des données à charger au type CHAR : cela évite les erreurs de typage.
Si j'ai des montants, ils sont alors exprimés sans virgule (par exemple: ils sont multipliés par 100 dans le fichier de données) et c'est dans mon trigger que je fais les conversions qui s'imposent.

A présent, c'est à toi de jouer ;-)

J'attends avec impatience le compte rendu de tes découvertes Oracle.
@+
1
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
3 janv. 2010 à 20:19
Bonsoir CodeForEver,

A ma connaissance, l'ordre d'insertion multiple que tu as donné ne fait pas partie du sql standard tel celui d'oracle par exemple.

En langage SQL pur, pour lancer un ordre d'insertion miltiple, il te faut écrire :

1- soit un ordre du style :

  INSERT INTO uneTable 
    SELECT colonne1, .... , colonneN
      FROM uneTable
      WHERE ...
      [ORDER BY ....]


2- soit lancer un ordre SQL qui produit autant d'ordre SQL d'insertion simple que tu as besoin

3- soit rédiger un programme PL/SQL qui parcourrera un curseur et pour chaque ligne de ton curseur lancera un ordre d'insertion (simple).

Si ton ordre d'insertion multiple fonctionne sous Oracle ... je ferais alors une découverte grâce à toi CodeForEver ;-)
0
blux Messages postés 26439 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 3 novembre 2024 3 312
4 janv. 2010 à 09:59
Salut,

c'est pour quel SGBD ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
codeForEver Messages postés 16 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 1 novembre 2011
4 janv. 2010 à 20:02
Bonsoir,

BadGuitariste : justement ça ne marche pas sous Oracle c'est pourquoi j'ai posé la question mais c'est vrai que je n'avais pas indiqué que c'est sous Oracle ...

du coup la réponse à Blux : c'est une base sous Oracle ...
(j'entre le code par sqlplus et utilise sqlDeveloper que pour vérifier le résultat)

Hyper débutante (c'est un tp de lécole) finalement j'ai fait 4 insert into pour mes 4 lignes ...

dans un tuto (http://sql.1keydata.com/fr/sql-insert-into.php) il propose de créer une table avec les données à insérer et insérer la nouvelle table ...

INSERT INTO "table1" ("column1", "column2", ...)
SELECT "column3", "column4", ...
FROM "table2"
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
4 janv. 2010 à 20:27
Bonsoir CodeForEver,

Ton 2ième tutorial respecte bien une écriture SQL standard de requête d'"insertions multiples" : cela correspond à la méthode (1) de ma réponse précédante.
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
5 janv. 2010 à 03:44
Petit complément à ton prolème d'insertions multiples sous Oracle,
si tu ne te limite pas au langage SQL alors tu peux utiliser l'outil sqlloader (%ORACLE_HOME%\BIN\sqlldr.exe) qui te permettra de charger dans ta base le contenu d'un fichier texte structuré.

Si cela t'intéresse, je peux t'aider à mettre en place une telle solution.
0
codeForEver Messages postés 16 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 1 novembre 2011
6 janv. 2010 à 00:12
Bonsoir BadGuitarist,

Merci bcp de tes réponses.
C'est super gentil ta proposition de m'aider pour la solution de sqlldr.
à savoir que je suis débutante et n'y connais pas de grand'chose si ça ne te fait pas perdre bcp de temps...

merci et à +
0
Utilisateur anonyme
6 janv. 2010 à 12:15
J'aimerais bien voir ton fichier de données
0
codeForEver Messages postés 16 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 1 novembre 2011
7 janv. 2010 à 00:23
salut BadGuitarist,

j'avais envoyé le message no 9 mais entre temps j'ai avancé un peu ;-)

ton explication m'a donné l'idée de voir plus sur le sujet

sur :
https://jaouad.developpez.com/sqlldr/#LIII-A

j'ai trouvé la syntaxe pour accéder au sqlldr mais il y a encore du boulot pour que ça marche :-)
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
7 janv. 2010 à 12:07
Bonjour CodeForEver,

Désolé pour la promesse de Normand. J'ai eu exceptionnellement du travail hier ;-)

La commande de lancement de SqlLoader sera du style (sur une même ligne DOS) :

    C:\ORANTV9\bin\SQLLdr USERID=tonLogin/tonMotDePasse@tonSIDBD
                                         CONTROL=load_annuaire_SAP.ctl
                                         LOG=load_annuaire_SAP.log
                                         BAD=load_annuaire_SAP.bad
                                         DATA=Z_telecom.txt
                                         ERRORS=9999
                                         ROWS=1000


   USERID    : ta connexion BD
   CONTROL : description de ton chargement (je te donnerai après un exemple)
   LOG         : fichier de traces
   BAD         : fichier des lignes rejetées (le fichier a la même structure que le fichier de données)
   DATA       : ton fichier de données
   ERRORS   : nombre d'erreurs maxi. que tu acceptes de rencontrer; au delà, arrêt du chargement imposé
   ROWS      : un COMMIT (validation) est fait toutes les n lignes chargées dans la base


... la suite au prochain post ...
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
7 janv. 2010 à 12:40
... suite (description du fichier à charger) de la procédure SQLLoader ...

Le contenu du fichier de données (simple fichier texte) pointé par le paramètre DATA ressemble donc à cela :

00017478;RODRIGUEZ;MICHEL
00000042;LASAYGUES;BERNARD
00021769;CAM;TIENGKHAM

etc ...

Tu remarqueras que le séparateur de champ que j'ai choisi est le point-virgule. Tu pouvais très bien choisir le | ou la tabulation ... le principal étant de le mentionner dans le fichier de contrôle (CONTROL).

... la suite (le fichier de contrôle) au prochain post ...
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
7 janv. 2010 à 12:56
... suite ... description du fichier de contrôle :

Le fichier de contrôle décrit la table d'accueil des enregistrements contenus dans le fichier de données.
Le contenu du fichier de contrôle appelé précédemment load_annuaire_SAP.ctl ressemblera à ceci :

LOAD DATA
REPLACE
INTO TABLE annuaire_SAP_V2
TRAILING NULLCOLS
(
  IDT_ASAP           CHAR   TERMINATED BY ";",
  NOM_ASAP         CHAR   TERMINATED BY ";",
  PRE_NOM_ASAP  CHAR   TERMINATED BY WHITESPACE
)


REPLACE : pour indiquer que les données déjà présentes dans la table d'accueil seront écrasées
INTO TABLE : nom d la table dans laquelle tu va insérer le contenu de ton fichier de données (DATA)
IDT_ASAP : 1ière colonne de la table annuaire_SAP_V2
NOM_ASAP : 2ième colonne de la table annuaire_SAP_V2
PRE_NOM_ASAP : 3ième colonne de la table annuaire_SAP_V2
CHAR : le type de données "SQLLOADER" correspondant au type VARCHAR2 des colonnes de tables
TERMINATED BY : le séparateur de champ

remarque : sur le dernier champ, il n'ya pas le séparateur habituel d'où le mot clé WHITESPACE

... suite (conseil(s)) au prochain post ...
0
codeForEver Messages postés 16 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 1 novembre 2011
8 janv. 2010 à 01:05
Salut BadGuitarist,

C'est super génial ce que t'envoie !!! mille merci ;-)

Avec ton cours et mes ' tites ' recherches sur net .... j'ai fini par avancer un peu !!

mise à part le temps fou que j'ai perdu à cause de pb de syntax machin ou @ du fichier .ctl que je ne marquais pas complète le reste ça va.
... quand on est débutant le chemin est long ! mais on y arrive ;-)

Pour nos moutons : impossible de faire marcher avec
INFILE donnees.dat
j'ai fini par mettre mes données dans .ctl et j'ai gardé une seule
FIELDS TERMINATED BY ','
pour toutes les colonnes ça donne :

LOAD DATA
INFILE *
INTO TABLE maTable
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
(prenom,ville,num)

BEGINDATA
Jean,"Lyon",253
Marie,"Bordeaux",145
Yves,"Lille",102

et figure toi que ça marche !!!

Par contre si les données vont dans .bad comment tu les corriges et les récupères ?

et pour PL/SQL
Normalement je dois lire le chapitre ... j'espère m'y mettre bientôt...

Merci encore et à bientôt ;-)
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
8 janv. 2010 à 17:17
Bonjour CodeForEver,

Bien ! ... Félicitations pour ta réussite et pour ta persévérance ;-)

Petite remarque : si tu n'as pas pu charger les données contenues dans un fichier ".txt" (par exemple), c'est peut-être parce que tu n'as pas mentionné le path :
    C:\ORANTV9\bin\SQLLdr USERID=tonLogin/tonMotDePasse@tonSIDBD
                                         CONTROL=c:\tests\insertionMultiple\load_annuaire_SAP.ctl
                                         LOG=c:\tests\insertionMultiple\load_annuaire_SAP.log
                                         BAD=c:\tests\insertionMultiple\load_annuaire_SAP.bad
                                         DATA=c:\tests\insertionMultiple\Z_telecom.txt
                                         ERRORS=9999
                                         ROWS=1000

Dans l'exemple que je t'avais donné, je supposais que tu étais positionnée dans le répertoire de travail où se trouvait le fichier à charger.

En ce qui concerne le problème de la récupération des lignes rejetées dans le fichier ".bad",
1- Etape 1 :
- dans ton cas (données intégrées au fichier .ctl),
il te faut copier-coller le contenu du fichier .bad et le mettre dans ton fichier .ctl (si besoin,
tu sauvegardes le fichier de contrôle avant modification pour conserver la trace de tes insertions).
- dans mon cas (données contenues dans un fichier de données),
tu sauvegardes ton fichier de données et tu renommes le fichier .bad avec le même nom que ton fichier
de données (avant renommage ;-)
2- Etape 2 :
Tu relances la commande SQLLOADER
(attention si tu as choisi l'option REPLACE dans ton fichier de contrôle).

Bien sûr, en étape 0, il aura fallu comprendre pourquoi les données ont été rejetées (et donc avoir corrigé le problème; en général, c'est une contrainte du genre colonne non nulle ou longueur max dépassée.

PS. :
pour ce qui est du PL/SQL, tu ne devrais pas avoir beaucoup de problème. Ce n'est pas un langage bien compliqué. Mais, si besoin, j'essaierai de répondre à tes interrogations.

A bientôt.
0
codeForEver Messages postés 16 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 1 novembre 2011
9 janv. 2010 à 11:26
Salut BadGuitarist,

Merci de ta réponse et ta présence ;-)

--------- pour l'histoire de .ctl

Pour charger les données depuis le fichier .dat j'avais essayer tout ce qui est le chemin du fichier, son répertoire (qui est le même que tout les autres fichier, etc)

Finalement après une bonne nuit blanche (comme la neige !!) je me suis persuadée que c'est dû à windows, car je travail sous windows.

un tuto du oracle, pour windows parle que d'intégration des données dans le fichier .clt finalement j'ai fait la paix et je l'ai accepté !!

Et en plus ça marche donc je ne vais pas compliquer !!
Par contre je vais corriger mon code (grâce à un point qui m'a sauté aux yeux grâce à ta note de l'Etape 2).
c'est que ma code est :

LOAD DATA
INFILE *
APPEND INTO TABLE MACHIN
FIELDS TERMINATED....


et bien tu parles de REPLACE ... eh oui c'est ça qu'il faut car quand je refais la même manipe (pour le moment) il double les lignes (à cause de APPEND).

par contre je ne sais pas s'il replace les données existantes et intèger en suite les nouvelles ... je vais essayer ça tout à l'heure.

--------- pour l'histoire de .bad

Merci de ton aide ça aussi je vais essayer tout à l'heure : tu vois que j'ai prévu un super bon week-end !!!

--------- pour l'histoire de PL/SQL

Merci de ton encouragement et ta générosité... donc on en parlera dans les jours qui viennent ;-)

Passe une super belle journée
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
9 janv. 2010 à 13:34
Bonjour CodeForEver,

En effet, il semblerait que tu vas passer un week-end très studieux.
Pour ce qui est du fichier .ctl (mais je n'insiste pas : tu as une solution qui marche ;-), il se peut que dans tes chemins, tes répertoires ont des espaces ... et là, sous windows, ça coince.

Concernant l'option REPLACE, je suis intéressé par le résultat de ton test : car je sais que c'est utilisé pour écrasé le contenu de la table dans laquelle on insère ... mais je crois (mais je ne suis plus sûr) qu'avec cette option, sqlloader vide d'abord la table puis fait les insert.

@+
0
codeForEver Messages postés 16 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 1 novembre 2011
10 janv. 2010 à 16:20
Salut BadGuitarist,

c'est vrai que mon week-end est studieux !!!
entre deux lignes de java (eh oui java aussi !!!) j'ai donc essayé mon code avec ton idée "REPLACE" ...

ce n'est pas pour te faire plaisir que je dis ça mais effectivement c'est le meilleur ;-)
il ajoute les nouvelles données sans doublonner les anciennes : chouette non ?

qu'il vide la table, ou il remplace les anciens par eux-mêmes c'est son affaire pourvu que le résultat soit bon et c'est le cas ! (au moins avec les exemples divers que j'ai fait).

Par contre je n'ai pas pu voir pour le fichier .bad pour le moment (je le mets sur le dos de java !) dès que je le fait je te fais signe ;-)

bon après midi
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
10 janv. 2010 à 17:36
Salut CodeForEver,

Ravi de voir que tes efforts (et mes quelques infos) ne sont pas vains.

Et bonne fin de week-end tout de même ,-)
0
BadGuitarist Messages postés 367 Date d'inscription dimanche 12 octobre 2008 Statut Membre Dernière intervention 20 octobre 2013 27
11 janv. 2010 à 07:25
Salut CodeForEver,

Juste un petit post (enfin ... je vais essayer !) pour te dire que j'ai trouvé (j'en suis sûr) le pourquoi de l'impossibilité de mettre tes données à charger dans un fichier externe : c'est à cause de l'option INFILE *.
Le chargement écrit ainsi :
  LOAD DATA
    REPLACE
    INTO TABLE

prendrait alors en compte le fichier désigné par le paramètre DATA de ta ligne de commande :
  SQLLdr USERID=tonLogin/tonMotDePasse@tonSIDBD CONTROL=fic_controles.ctl DATA=fic_donnees.txt ...


Bon ... je suis un vrai pitbull : tant que j'ai un os à ronger (= un problème informatique non résolu), je continue à chercher ... à la limite, j"en deviendrais casse-pieds ;-)
Mais là, je crois que toutes les facettes du problème ont été vues.

Bonne journée.
0
codeForEver Messages postés 16 Date d'inscription vendredi 1 janvier 2010 Statut Membre Dernière intervention 1 novembre 2011
22 janv. 2010 à 04:12
Salut BG,

Merci bcp de ton message, je l'ai lu que là avec bcp de retard ...

Tu sais moi aussi par fois je continue à chercher alors que qq'un de plus "normal" (!!!) aurait oublié le sujet !!!
Du coup je ré-essayé ton code mais toujours les mêmes réponses :-(

dans mon fhicher.clt j'ai :

LOAD DATA
    REPLACE  INTO TABLE matable
    FILED TERMINED BY ...
(col1, col2, ...)


sur le console je mets les lignes

sqlldr monlogin/monpw

entrer
il affiche
control=

j'y ajout le path de mon fichier.clt
entrer et message d'erreur :-(

et si après le path de fichier.clt j'ajout le path de fichier .dat c'est encore pire ...
en attendant je m'en suis sortie en intégrant les données dans le fichier .clt mais on ne peut pas le faire toujours c'est pourquoi j'aurais aimé trouver la solution pour ça ...
mais avec tout aide et gentillesse que tu m'adresse le problème persiste...

en tout cas on y arrivera ;-)
0