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

Oracle Discussion :

Requête update à plusieurs sélections


Sujet :

Oracle

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2010
    Messages
    163
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 163
    Points : 77
    Points
    77
    Par défaut Requête update à plusieurs sélections
    Bonjour à tous,

    J'ai deux tables: table testt formée de 4 colonnes (Libe, col1, col2, col3)
    et une table testt_source formée de 3 colonnes (Libe, test1, test2).

    Voici la table testt_source :
    LIBE            TEST1      TEST2
    ---------- ---------- ----------
    col1                1          2
    col2                3          4
    col3                7          8
    Voici la table testt :
    LIBE             COL1       COL2       COL3
    ---------- ---------- ---------- ----------
    test1
    test2
    j'aimerai mettre à jour la table testt de sorte que la colonne col1 par exemple ait comme valeurs (1 , 2).

    Pour ce faire j'ai exécuté la requête update suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    update testt set 
      ((testt.col1 = (select tt_sou.test1 from testt_source tt_sou where tt_sou.libe = 'col1') where testt.libe = 'test1') 
       and (testt.col1 =(select tt_sou.test2 from testt_source tt_sou where  tt_sou.libe = 'col1') where testt.libe = 'test2'))
    Mais elle me renvoie l'erreur :

    ORA-01747 invalid user.table.column, table.column, or column specification
    Est ce que je pourrais trouver de l'aide, svp

    Merci.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 453
    Points : 18 394
    Points
    18 394
    Par défaut
    Votre syntaxe d'update ne représente rien.
    Avez-vous cherché dans les tutoriels disponibles ?

  3. #3
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    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
    20
    21
    22
     merge into testt t
     using (select new_libe,
                   max(case when libe = 'col1' then new_val end) as col1,
                   max(case when libe = 'col2' then new_val end) as col2,
                   max(case when libe = 'col3' then new_val end) as col3
    		  from (select s.libe,
                           case when p.rn = 1 then 'test1'
                                when p.rn = 2 then 'test2'
                            end as new_libe,
                           case when p.rn = 1 then s.test1
                                when p.rn = 2 then s.test2
                            end as new_val
                      from testt_source s
                     cross join (select rownum as rn from dual connect by level <= 2) p
    		       )
    		 group by new_libe
    		) u
        on t.libe = u.new_libe
      when matched then
    update set t.col1 = u.col1,
           set t.col2 = u.col2,
           set t.col3 = u.col3
    D'abord pivoter les colonnes en ligne le CROSS JOIN où 2 (dans connect by level <= 2) correspond aux nombres de colonnes de testt_source à pivoter.
    Puis pivoter les lignes en colonnes (max(case when...)) pour que le select ressemble à la table testt.
    Puis merge la requête dans testt.
    Evidemment c'est assez statique car il faut hard coder les noms de colonnes.
    Je n'ai pas testé la requête donc elle ne fonctionne peut être pas telle quelle mais je pense que le concept est valide.

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    J'avais fais 2 erreurs de syntaxes, je reposte la requête correcte :
    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
    20
    21
    22
    23
     
     merge INTO testt t
     USING (SELECT new_libe,
                   max(case when libe = 'col1' then new_val end) AS col1,
                   max(case when libe = 'col2' then new_val end) AS col2,
                   max(case when libe = 'col3' then new_val end) AS col3
              FROM (SELECT s.libe,
                           case when p.rn = 1 then 'test1'
                                when p.rn = 2 then 'test2'
                            end AS new_libe,
                           case when p.rn = 1 then s.test1
                                when p.rn = 2 then s.test2
                            end AS new_val
                      FROM testt_source s
                     CROSS JOIN (SELECT rownum AS rn FROM dual connect BY level <= 2) p
                   )
             GROUP BY new_libe
           ) u
        ON (t.libe = u.new_libe)
      when matched then
    UPDATE SET t.col1 = u.col1,
               t.col2 = u.col2,
               t.col3 = u.col3
    et le jeu de test :
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    SQL> create table testt (Libe varchar2(10), col1 number, col2 number, col3 number)
      2  /
     
    Table created.
     
    SQL> create table testt_source (Libe varchar2(10), test1 number, test2 number)
      2  /
     
    Table created.
     
    SQL> insert into testt_source values ('col1',1,2);
     
    1 row created.
     
    SQL> insert into testt_source values ('col2',3,4);
     
    1 row created.
     
    SQL> insert into testt_source values ('col3',7,8);
     
    1 row created.
     
    SQL> 
    SQL> insert into testt (libe) values ('test1');
     
    1 row created.
     
    SQL> insert into testt (libe) values ('test2');
     
    1 row created.
     
    SQL> 
    SQL> commit;
     
    Commit complete.
     
    SQL> 
    SQL> select * from testt_source;
     
    LIBE            TEST1      TEST2
    ---------- ---------- ----------
    col1                1          2
    col2                3          4
    col3                7          8
     
    SQL> select * from testt;
     
    LIBE             COL1       COL2       COL3
    ---------- ---------- ---------- ----------
    test1
    test2
     
    SQL> 
    SQL>  merge INTO testt t
      2   USING (SELECT new_libe,
      3                 max(case when libe = 'col1' then new_val end) AS col1,
      4                 max(case when libe = 'col2' then new_val end) AS col2,
      5                 max(case when libe = 'col3' then new_val end) AS col3
      6            FROM (SELECT s.libe,
      7                         case when p.rn = 1 then 'test1'
      8                              when p.rn = 2 then 'test2'
      9                          end AS new_libe,
     10                         case when p.rn = 1 then s.test1
     11                              when p.rn = 2 then s.test2
     12                          end AS new_val
     13                    FROM testt_source s
     14                   CROSS JOIN (SELECT rownum AS rn FROM dual connect BY level <= 2) p
     15                 )
     16           GROUP BY new_libe
     17         ) u
     18      ON (t.libe = u.new_libe)
     19    when matched then
     20  UPDATE SET t.col1 = u.col1,
     21             t.col2 = u.col2,
     22             t.col3 = u.col3
     23  /
     
    2 rows merged.
     
    SQL> 
    SQL> select * from testt;
     
    LIBE             COL1       COL2       COL3
    ---------- ---------- ---------- ----------
    test1               1          3          7
    test2               2          4          8
     
    SQL>

  5. #5
    Membre régulier
    Inscrit en
    Novembre 2010
    Messages
    163
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 163
    Points : 77
    Points
    77
    Par défaut
    Bonjour,

    Merci énormément pour ces clarifications
    J'ai adapté ton code à mon cas réel, voici le code

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
     
        merge INTO tb_gisement t 
         USING (SELECT new_libe,
                      max(case when DIM_ANALYSE = 'NBR DE CLIENT' then new_val end) AS NBR_CLT_EQ,
                      max(case when DIM_ANALYSE = 'CLIENTS CIBLE' then new_val end) AS POP_CIBLE_EQ,
                      max(case when DIM_ANALYSE = 'CIBLE NON EQUIPES' then new_val end) AS CIBLE_NN_EQ
                 FROM (SELECT s.libe,
                              case when p.rn = 1 then 'SICAV'
                                   when p.rn = 2 then 'TPE'
                                   when p.rn = 3 then 'CARTE_AFF'
                                   when p.rn = 4 then 'BIATNET'
                                   when p.rn = 5 then 'MULTIVIR'
                                   when p.rn = 6 then 'CARTE_SAL'
                                   when p.rn = 7 then 'SD_CHANGE'
                                   when p.rn = 8 then 'CPT_DEV'
                                   when p.rn = 9 then 'AVA'
                                   when p.rn = 10 then 'COMEX'
                                   when p.rn = 10 then 'NEG_SDM'
                                   when p.rn = 12 then 'BIATCAPITAL'
                                   when p.rn = 13 then 'PROTECTRICE'
                                   when p.rn = 14 then 'DAB'
                                   when p.rn = 15 then 'CONVENTION'
                               end AS new_libe,
                              case when p.rn = 1 then s.SICAV
                                   when p.rn = 2 then s.TPE
                                   when p.rn = 3 then s.CARTE_AFF
                                   when p.rn = 4 then s.BIATNET
                                   when p.rn = 5 then s.MULTIVIR
                                   when p.rn = 6 then s.CARTE_SAL
                                   when p.rn = 7 then s.SD_CHANGE
                                   when p.rn = 8 then s.CPT_DEV
                                   when p.rn = 9 then s.AVA
                                   when p.rn = 10 then s.COMEX
                                   when p.rn = 11 then s.NEG_SDM
                                   when p.rn = 12 then s.BIATCAPITAL
                                   when p.rn = 13 then s.PROTECTRICE
                                   when p.rn = 14 then s.DAB
                                   when p.rn = 15 then s.CONVENTION
                             end AS new_val
                        FROM vue_gisement s
                       CROSS JOIN (SELECT rownum AS rn FROM dual connect BY level <= 15) p
                     )
               GROUP BY new_libe
              ) u
           ON (t.produits = u.new_libe)
        when matched then
       UPDATE SET t.SICAV = u.SICAV,
               t.TPE = u.TPE,
               t.CARTE_AFF = u.CARTE_AFF
               t.BIATNET = u.BIATNET
               t.MULTIVIR = u.MULTIVIR
               t.CARTE_SAL = u.CARTE_SAL
               t.SD_CHANGE = u.SD_CHANGE
               t.CPT_DEV = u.CPT_DEV
               t.AVA = u.AVA
               t.COMEX = u.COMEX
               t.NEG_SDM = u.NEG_SDM
               t.BIATCAPITAL = u.BIATCAPITAL
               t.PROTECTRICE = u.PROTECTRICE
               t.DAB = u.DAB
               t.CONVENTION = u.CONVENTION
    Mais il me renvoie l'erreur suivante :


    ORA-00933 SQL command not properly ended

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Normalement tu essaies d'update les colonnes NBR_CLT_EQ, POP_CIBLE_EQ, CIBLE_NN_EQ de tb_gisement donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE SET t.NBR_CLT_EQ = u.NBR_CLT_EQ,
               t.POP_CIBLE_EQ = u.POP_CIBLE_EQ,
               t.CIBLE_NN_EQ = u.CIBLE_NN_EQ
    Si ça n'est pas le cas il faudra réexpliquer le besoin.

  7. #7
    Membre régulier
    Inscrit en
    Novembre 2010
    Messages
    163
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 163
    Points : 77
    Points
    77
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Normalement tu essaies d'update les colonnes NBR_CLT_EQ, POP_CIBLE_EQ, CIBLE_NN_EQ de tb_gisement donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE SET t.NBR_CLT_EQ = u.NBR_CLT_EQ,
               t.POP_CIBLE_EQ = u.POP_CIBLE_EQ,
               t.CIBLE_NN_EQ = u.CIBLE_NN_EQ
    Si ça n'est pas le cas il faudra réexpliquer le besoin.
    Merci infiniment pour ta coopération, tu m'as sauvé la vie

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Requête update à partir d'une autre table
    Par amiral thrawn dans le forum Langage SQL
    Réponses: 5
    Dernier message: 15/02/2024, 12h40
  2. Requête oracle : update et sélection...
    Par Requin15 dans le forum Langage SQL
    Réponses: 10
    Dernier message: 27/03/2006, 20h32
  3. requête update qui marche pas
    Par MrsFrizz dans le forum Langage SQL
    Réponses: 4
    Dernier message: 01/12/2004, 09h16
  4. PB Requête update
    Par cassi2 dans le forum Langage SQL
    Réponses: 9
    Dernier message: 25/10/2004, 15h15
  5. [BDE]requête dans plusieurs bases
    Par sbeu dans le forum Bases de données
    Réponses: 2
    Dernier message: 01/03/2004, 10h24

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