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

PL/SQL Oracle Discussion :

Insert et select en PL/SQL


Sujet :

PL/SQL Oracle

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 31
    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 !!!


  2. #2
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO tab3
    SELECT id FROM tab1
    UNION ALL
    SELECT id FROM tab2;
    non ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 31
    Par défaut
    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.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 31
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  5. #5
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    comment tu couples les id de tab1 et tab2 ?

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 31
    Par défaut
    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

  7. #7
    Membre Expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Par défaut
    Pour éviter ce genre d'erreurs, on précise systématiquement les colonnes à inserer ou selectionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    insert into matable (col1, col2, col3)
    select A,B,C from ...
    et non
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    insert into matable
    select * from ...

  8. #8
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    c'est un problème fonctionnel... je vois pas comment on pourrait t'aider

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 31
    Par défaut
    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+

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 31
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  11. #11
    Membre Expert
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Par défaut
    Est-ce que c'est important à l'arrivée tu as:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    t1.ID   t2.ID
    ------------
    1        14
    1        15
    2        11
    2        13
    3        12
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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...

  12. #12
    Membre Expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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  ...

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 31
    Par défaut
    Citation Envoyé par remi4444
    Est-ce que c'est important à l'arrivée tu as:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    t1.ID   t2.ID
    ------------
    1        14
    1        15
    2        11
    2        13
    3        12
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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


  14. #14
    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 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 77
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  16. #16
    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 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 ?

  17. #17
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 77
    Par défaut
    Ca existe depuis la 9i je crois... la toute premiere 9
    En 8i, c'est possible mais il faut vérifier

  18. #18
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    un FULL OUTER ne peut-il être fait en faisant un produit cartésien ?

  19. #19
    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 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 Images attachées  

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 31
    Par défaut
    Super les gars. Je m'y attèle en fin de journée. Merci pour toutes ces infos, Je vous tiens au courant!!!


Discussions similaires

  1. [SQL] Insert into select(s)
    Par tidou95220 dans le forum SAS Base
    Réponses: 3
    Dernier message: 25/03/2013, 12h14
  2. [SQL] Problème de guillemets dans un INSERT INTO SELECT
    Par Lenezir dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 25/02/2008, 14h21
  3. hibernate sql insert vs select
    Par mauroyb0 dans le forum Hibernate
    Réponses: 11
    Dernier message: 27/03/2007, 16h32
  4. Réponses: 1
    Dernier message: 22/09/2006, 13h56
  5. SQL : syntaxe insert into select
    Par chrislauxerrois dans le forum Access
    Réponses: 15
    Dernier message: 31/07/2006, 16h12

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