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

SQL Oracle Discussion :

Update d'une table en fonction du résultat d'une autre requête


Sujet :

SQL Oracle

  1. #1
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut Update d'une table en fonction du résultat d'une autre requête
    Bonjour à vous,

    Je vais essayer de bien synthétiser à ma question.

    J'ai une requete SQL A qui me renvoie plusieurs lignes d'un couple de deux clés , soit cle1 et cle2.

    Je veux maintenant mettre à jour une table B par un update qui devrait ressembler à mon exemple ....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Update MATABLE set MACOLONNE1_FK = (Select COLONNE                                      
    From tableX, tableY
    Where ......
       and COLONNE_FK=cle 1)
    Where MACOLONNE2_FK=cle 2
    J'avoue me demander comment faire et si cela est bien possible

    Merci pour votre aide

  2. #2
    Membre averti Avatar de LBO72
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Points : 342
    Points
    342
    Par défaut
    Avec du PlSql, je vois quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    begin
    ...
      for cur in (Select COLONNE, cle2 
                    From tableX, tableY
                    Where ......
                       and COLONNE_FK=cle 1) loop
     
           execute immediate 'Update MATABLE set MACOLONNE1_FK = :v1 
                                     where MACOLONNE2_FK = :v2' 
                                     using cur.COLONNE, cur, cur.cle2;
      end loop;
    End
    /
    Qu'en penses-tu ?
    Cdlt,
    LBO72.

  3. #3
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Points : 1 359
    Points
    1 359
    Par défaut
    Citation Envoyé par LBO72 Voir le message
    Avec du PlSql, je vois quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    begin
    ...
      for cur in (Select COLONNE, cle2 
                    From tableX, tableY
                    Where ......
                       and COLONNE_FK=cle 1) loop
     
           execute immediate 'Update MATABLE set MACOLONNE1_FK = :v1 
                                     where MACOLONNE2_FK = :v2' 
                                     using cur.COLONNE, cur, cur.cle2;
      end loop;
    End
    /
    Qu'en penses-tu ?
    Cdlt,
    LBO72.
    Pourquoi du dymanique SQL???? Est-il en train de faire du DDL???

  4. #4
    Membre averti Avatar de LBO72
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Points : 342
    Points
    342
    Par défaut
    On peut bien evidement l'écrire comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    begin
    ...
      FOR cur IN (SELECT COLONNE, cle2 
                    FROM tableX, tableY
                    WHERE ......
                       AND COLONNE_FK=cle 1) loop
     
              Update MATABLE set MACOLONNE1_FK = COLONNE 
                                     where MACOLONNE2_FK = cle2;
      end loop;
    End
    /
    Mais ça sera moins performant(pour des grosses volumétries), puisque l'optimiseur va calculer le plan d'exécution à chaque itération. En utilisant le Sql Dynamique et les bind variables, on évitera cette étape.

    Cdlt,
    LBO72.

  5. #5
    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
    Citation Envoyé par LBO72 Voir le message
    Mais ça sera moins performant(pour des grosses volumétries), puisque l'optimiseur va calculer le plan d'exécution à chaque itération. En utilisant le Sql Dynamique et les bind variables, on évitera cette étape.
    Non le PL/SQL utilise automatiquement des bind varaiables, pas besoin d'execute immediate.
    Après pourquoi faire un curseur plutôt qu'une seule requête, avec MERGE on peut écrire quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    merge into matable
    using (SELECT COLONNE, cle2 
             FROM tableX
             join tableY ON COLONNE_FK=cle1
            WHERE ......) u
       on (MACOLONNE2_FK = cle2)
     when matched then
      SET MACOLONNE1_FK = COLONNE

  6. #6
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Points : 1 359
    Points
    1 359
    Par défaut
    Citation Envoyé par LBO72 Voir le message
    Mais ça sera moins performant(pour des grosses volumétries), puisque l'optimiseur va calculer le plan d'exécution à chaque itération. En utilisant le Sql Dynamique et les bind variables, on évitera cette étape.
    Cdlt,
    LBO72.
    Un petit rappel
    Les "bind variables" ont des avantages et des inconvénients. Leur avantage vient du fait qu'elles permettent la réutilisation (ou le partage) des curseurs qui se trouvent dans la SGA (particulièrement dans la "library cache") et, donc, évitent le "hard parse" et ses effets sur la performance au travers du temps que celui-ci nécessite de la part de la CPU (le "hard parse" brule beaucoup de CPU)
    Quant à leurs inconvénients, on peut le dire, elles ne s'entendent pas aves les histogrammes. On créé des histogrammes parce que des requêtes identiques génèrent un temps de réponse et un volume de données très différents l'un de l'autre et nous ne voulons pas que ces requêtes identiques utilisent (ou partage) le même explain plan.

    Quelle contradiction!!!

    L'un (bind variable) est pour le partage et la réutilisation du même curseur (même plan d'exécution) et l'autre est pour que chaque requête ait son propre plan d'exécution
    C’est pourquoi en règles général des personnes comme Tom Kyte suggèrent :
    1. d’utiliser les bind variables en OLTP
    2. de ne pas utiliser des histogrammes en OLTP
    3. d’utiliser des histogrammes en DWH

    Le petit rappel étant fait, j’aimerai enchainer sur votre réponse pour dire qu’en utilisant du PL/SQL (sql statique tel que procédure stockée) nous avons l’avantage qu’un genre de ‘’binding’’ automatique est fait pour nous. Nous n’avons pas à nous soucier de cela. Nous devrions quand même veiller à ce que les appels de cette procédure soit faits avec des paramètres déclarés en ‘bind variables’’. Sinon, notre libray cache (v$sql) sera remplie d’appel à notre procédure.
    Par contre lorsque vous proposez d’utiliser le sql dynamique dans une procédure stockée, là vous devriez faire attention à la bonne utilisation des bind variables. Le concept de ‘’binding’’ automatique disparaît et vous devriez redoubler d'attention quant à l'utilisation de ces variables sans parler des riques (sql injection) que vous pourriez introduire dans votre application lorsque des concaténations sont utilisées. Quant au calcul du plan d’exécution à chaque itération, j’espère que le petit rappel a atteint son but.

  7. #7
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Mohamed.Houri Voir le message
    ...On créé des histogrammes parce que des requêtes identiques génèrent un temps de réponse et un volume de données très différents l'un de l'autre et nous ne voulons pas que ces requêtes identiques utilisent (ou partage) le même explain plan.
    ...
    Les histogrammes sont apparus en Oracle 9 pour répondre à une des critiques majeures apportées à l’optimiseur basée sur le coût d'Oracle 8, celui de l’hypothèse d’une distribution uniforme des données (voir Wolfgang Breitling "Fallacies of the cost based optimiser"). Les cases de distribution non-uniforme des données peuvent être décrites avec des histogrammes ce qui permet par la suite à l’optimiseur de trouver les "bons plans" d’exécution adaptées à chaque cas.

    Petit remarque : la réutilisation des curseurs date de la version 5/6 d’Oracle et ce mécanisme était à l’époque une réponse adaptée par rapport à l’optimiseur basée sur les règles. Mais l’optimiseur basée sur les règles n’existe plus … bref, il existe toujours mais…

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

Discussions similaires

  1. Update d'une table en fonction des champs d'une autre table
    Par The Molo dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 05/02/2008, 15h41
  2. Réponses: 2
    Dernier message: 13/12/2007, 15h02
  3. Réponses: 6
    Dernier message: 25/09/2006, 14h11
  4. UPDATER le champ d'une table 1 avec le champ d'une table 2
    Par alain.dissoir dans le forum Oracle
    Réponses: 2
    Dernier message: 08/06/2005, 13h07
  5. remplir une table en fonction des résultats
    Par Psychomantis dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 19/10/2004, 12h22

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