Précédent   Forum des professionnels en informatique > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
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 16/10/2006, 11h01   #1
Invité régulier
 
Inscription : juillet 2006
Messages : 26
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 26
Points : 6
Points : 6
Par défaut Insert et select en PL/SQL

Bonjour,

Je suis en train de faire un script en PL/SQL permettant d'alimenter une base de données.

Le problème est le suivant : j'ai deux tables que j'alimente grâce au script. Je dois par la suite alimenter une troisième table avec les données des deux tables alimentées auparavant.

Si vous avez bien compris le système, je dois faire un select sur les deux tables, et entrer le résultat dans la troisième table et insérant seulement les ID des deux tables.

En fait je voudrai savoir comment récupérer les valeurs (select) et les mettre dans une autre table (insert).

Je ne sais pas si je me suis bien exprimé, mais si quelqu'un pourrait m'éclairer sur ce problème, ça serait très sympa, merci !!!

Bonjovi51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/10/2006, 11h06   #2
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Code :
1
2
3
4
INSERT INTO tab3
SELECT id FROM tab1
UNION ALL
SELECT id FROM tab2;
non ?
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/10/2006, 11h24   #3
Invité régulier
 
Inscription : juillet 2006
Messages : 26
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 26
Points : 6
Points : 6
Merci de me répondre si vite

Oui, j'avais essayé mais à chaque fois Oracle me balance une exception :

SQL Error: ORA-00947: Nombre de valeurs insuffisant

Pourtant la troisième table a bien que deux champs à remplir. Je ne vois pas ce qu'il veut dire par là.

Alors je ne sais plus trop quoi faire.
Bonjovi51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/10/2006, 11h51   #4
Invité régulier
 
Inscription : juillet 2006
Messages : 26
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 26
Points : 6
Points : 6
Au fait, je sais pourquoi Oracle me met ce message d'erreur. J'ai donc compris pourquoi pas je n'arrive à insérer les valeurs.

En fait, la troisième table comprend deux champs. Un champ pour l'ID de la première table et le deuxième champ pour l'Id de la deuxième table.

Je voudrai insérer 50 ID de la deuxième table pour un ID de la première table

Exemple :
Code :
1
2
3
4
5
6
7
8
 
t1.ID   t2.ID
------------
1        11
1        12
2        13
2        14
3        15
Avez-vous une solution svp??

Merci
Bonjovi51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/10/2006, 11h56   #5
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
comment tu couples les id de tab1 et tab2 ?
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/10/2006, 14h00   #6
Invité régulier
 
Inscription : juillet 2006
Messages : 26
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 26
Points : 6
Points : 6
Bah justement,

C'est ce que je voudrai savoir. Comment faire pour les coupler.

En fait, je pensais d'abord faire un select de la table 1 pour récupérer les Id et ensuite faire une boucle pour de 1 à 50 pour insérer les Id de la table 2 pour un id de la table 1.

Mais je ne sais pas comment m'y prendre.

Si il y a plus simple, je suis preneur...

Merci
Bonjovi51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/10/2006, 14h06   #7
Expert Confirmé
 
Avatar de LeoAnderson
 
Inscription : septembre 2004
Messages : 2 942
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 2 942
Points : 2 972
Points : 2 972
Pour éviter ce genre d'erreurs, on précise systématiquement les colonnes à inserer ou selectionner :
Code :
1
2
3
 
INSERT INTO matable (col1, col2, col3)
SELECT A,B,C FROM ...
et non
Code :
1
2
INSERT INTO matable
SELECT * FROM ...
LeoAnderson est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/10/2006, 14h08   #8
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
c'est un problème fonctionnel... je vois pas comment on pourrait t'aider
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/10/2006, 14h12   #9
Invité régulier
 
Inscription : juillet 2006
Messages : 26
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 26
Points : 6
Points : 6
Ok, merci Leo et Fred.

Dans un premier temps je voulais savoir comment insérer des données dans une table à partir d'un select d'une autre table.

Maintenant, que j'ai la solution avec notamment le UNION ALL ou UNION ca devrait aller.

Je posterai la réponse lorsque j'aurai trouver la réponse.

Merci pour les réponses rapides

A+
Bonjovi51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2006, 18h59   #10
Invité régulier
 
Inscription : juillet 2006
Messages : 26
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 26
Points : 6
Points : 6
Bon, je n'ai toujours pas réussi ce que je voulais faire.

Je vais récapituler ce que je veux.

J'ai deux tables alimentées. t1 et t2 pour donner un exemple. Et je voudrai insérer les id de t1 et t2 dans une troisième table t3. La table t3 comprend deux champs.

Au final, je veux que cela donne ça dans t3

Code :
1
2
3
4
5
6
7
8
 
t1.ID   t2.ID
------------
1        11
1        12
2        13
2        14
3        15
J'ai fait un bout de code, mais cela ne marche pas mais je pense être sur la bonne voie.

Code :
1
2
3
4
5
6
7
8
9
10
 
nbGroupePr := 1000;
 
FOR i IN 1..nbGroupePr loop
   SELECT t1.ID FROM TABLE1 t1;
   FOR j IN 1..50 loop
      SELECT t2.ID FROM TABLE2 t2;				
      INSERT INTO TABLE3("ID_TABLE1","ID_TABLE2") VALUES(t1.ID,t2.ID);
   end loop;
end loop;
En fait ce que je ne sais pas faire, c'est comment récupérer l'ID de t1 ainsi que l'ID de t2 à partir du select.

Merci d'avance
Bonjovi51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2006, 19h10   #11
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
Est-ce que c'est important à l'arrivée tu as:

Code :
1
2
3
4
5
6
7
8
 
t1.ID   t2.ID
------------
1        14
1        15
2        11
2        13
3        12
ou

Code :
1
2
3
4
5
6
7
t1.ID   t2.ID
------------
1        13
1        15
2        11
2        12
3        14
ou ... ou ... ou y a-t-il une certaine règle à respecter ?

si règle il y a, il faut commencer par l'énoncer puis la donner à oracle, sinon y'a peu de chance qu'il devine tout seul...
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2006, 20h31   #12
Expert Confirmé
 
Inscription : février 2006
Messages : 3 433
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 3 433
Points : 3 462
Points : 3 462
Citation:
En fait ce que je ne sais pas faire, c'est comment récupérer l'ID de t1 ainsi que l'ID de t2 à partir du select.
Pour faire ça en PL/SQL (si on peut pas le faire directement en SQL comme on vous l'a déjà suggéré) il suffit de déclarer une variable de type t1.id et une variable de type t2.id et d'utiliser SELECT ... INTO:

Code :
1
2
3
4
5
6
 
v_t1id t1.id%TYPE;
v_t2id t2.id%TYPE;
....
SELECT t1.id INTO v_t1id FROM t1  ...
SELECT t2.id INTO v_t2id FROM t1  ...
__________________
P. Forstmann

AskTom Forums OTN doc 8, 9, 10 et 11
pifor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2006, 10h38   #13
Invité régulier
 
Inscription : juillet 2006
Messages : 26
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 26
Points : 6
Points : 6
Citation:
Envoyé par remi4444
Est-ce que c'est important à l'arrivée tu as:

Code :
1
2
3
4
5
6
7
8
 
t1.ID   t2.ID
------------
1        14
1        15
2        11
2        13
3        12
ou

Code :
1
2
3
4
5
6
7
t1.ID   t2.ID
------------
1        13
1        15
2        11
2        12
3        14
ou ... ou ... ou y a-t-il une certaine règle à respecter ?

si règle il y a, il faut commencer par l'énoncer puis la donner à oracle, sinon y'a peu de chance qu'il devine tout seul...
Non, non pas de règles.

Sinon, je vais utiliser la solution de pifor.

Merci de me répondre aussi vite

Bonjovi51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2006, 11h18   #14
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 Bonjovi51
Non, non pas de règles.
Tu peux alors faire une boucle générale, 2 fetch dans ta boucle, et tu sort au 1ier curseur qui fini (ou au dernier comme tu veux).

Tu peux aussi faire en une seule requête en utilisant une colonne de jointure arbitraire définie par le rownum:

Code :
1
2
3
4
5
INSERT INTO TABLE3 
 SELECT V1.ID, V2.ID FROM 
   (SELECT ID, ROWNUM AS N FROM TABLE1 ) V1,
   (SELECT ID, ROWNUM AS N FROM TABLE2 ) V2
 WHERE V1.N = V2.N
Dans la requête précédente, le remplissage se fera en fonction de la table la moins peuplée (si TABLE1 à 5 lignes et TABLE2 8 lignes, alors TABLE3 en aura 5)

Si tu veux que ta table3 se remplisse comme la table la plus peuplée et que tu ne sait pas à priori qui de T1 ou T2 contient le plus de monde, il faut un peu "bricoler" car la notion de "jointure externe double" n'existe pas sous oracle.

Par exemple en faisant une union / regroupement:

Code :
1
2
3
4
5
6
7
8
INSERT INTO TABLE3
 SELECT max(ID1), max(ID2) FROM
  (
  SELECT ID AS ID1, NULL AS ID2, ROWNUM AS N FROM TABLE1  
  UNION ALL
  SELECT NULL AS ID1, ID AS ID2, ROWNUM AS N FROM TABLE2  
  )
 GROUP BY N
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2006, 19h18   #15
Membre régulier
 
Inscription : octobre 2006
Messages : 77
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : octobre 2006
Messages : 77
Points : 73
Points : 73
Mais si, le full outer join existe avec Oracle , mais il faut utiliser une syntaxe full outer join pour que ça marche.

Tu peux le faire avec la syntaxe suivante :

Code :
1
2
3
4
 
SELECT id_cln, id_art FROM
(SELECT rownum n, id_cln FROM client WHERE rownum<15) t1 full OUTER JOIN
(SELECT rownum n, id_art FROM article WHERE rownum<10) t2 ON t1.n=t2.n
C'est un exemple que j'ai testé avec succès, en inversant les valeurs 15 et 10 (mes tables font plusieurs milliers de lignes, donc les limitations en nombre d'enregistrement me permettait de vérifier sur un petit nombre de données).

L'exemple de Rémi devient alors
Code :
1
2
3
4
5
 
INSERT INTO TABLE3 
 SELECT V1.ID, V2.ID FROM 
   (SELECT ID, ROWNUM AS N FROM TABLE1 ) V1 full OUTER JOIN
   (SELECT ID, ROWNUM AS N FROM TABLE2 ) V2 ON V1.N = V2.N
Le plan d'exécution n'est pas top, mais bon, c'est pas un traitement classique.

Un conseil : oubli le PL/SQL quand tu peut faire la même chose en SQL. Tout se qui se fait au niveau du noyau sera toujours bcp plus performant.

J'ai testé la requête sans mettre mes filtres : 18s pour créer/remplir la table t3 avec en sources t1 = 100Mo / 150 000 lignes et t2=3Mo / 10000 lignes, le tout sur un serveur qui n'a rien d'extraordinaire.

Cdlt
Hugues_78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 10h35   #16
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 Hugues_78
Mais si, le full outer join existe avec Oracle , mais il faut utiliser une syntaxe full outer join pour que ça marche.
Super, je savais pas! depuis quelle version ça existe ?
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 11h49   #17
Membre régulier
 
Inscription : octobre 2006
Messages : 77
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : octobre 2006
Messages : 77
Points : 73
Points : 73
Ca existe depuis la 9i je crois... la toute premiere 9
En 8i, c'est possible mais il faut vérifier
Hugues_78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 11h53   #18
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
un FULL OUTER ne peut-il être fait en faisant un produit cartésien ?
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 12h02   #19
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 Hugues_78
En 8i, c'est possible mais il faut vérifier
En 8i tu n'as droit que te faire les jointure avec les (+) et tu n'as pas le droit d'en mettre des 2 coté d'une égalité comme le montre la spec de la jointure externe de la doc 8.1.7:
Images attachées
Type de fichier : gif syntaxe_outer.gif (8,0 Ko, 12 affichages)
remi4444 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2006, 14h21   #20
Invité régulier
 
Inscription : juillet 2006
Messages : 26
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 26
Points : 6
Points : 6
Super les gars. Je m'y attèle en fin de journée. Merci pour toutes ces infos, Je vous tiens au courant!!!

Bonjovi51 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 17h27.


 
 
 
 
Partenaires

Hébergement Web