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 depuis un select


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 144
    Points : 97
    Points
    97
    Par défaut Update depuis un select
    Bonjour,

    J'ai une requête qui update un champ d'une table à partir d'un select. La requête est légèrement complexe puisque j'ai deux tables impliquées:

    - la table à updater tableA
    - la table tableB, liée à A par une clef
    - la table tableB (encore) liée à elle même par une autre clef

    L'idée est qu'une ligne de tableA est liée à une ligne de tableB, mais l'inverse n'est pas vrai. En pratique on a toujours deux lignes de B pour une ligne de A, avec une seule directement liée. (Je n'ai pas choisi cette structure :s).Le champ de la tableA à updater doit prendre la valeur de la ligne de B qui correspond à la ligne de B liée à la ligne de A et qui n'est pas lié à A. (ouf!)

    ligneA correspond directement (FK) à ligneB1 et à travers ligneB1 à ligneB2.

    L’identification se fait par un champ qui a la même valeur pour ligneB1 et ligneB2. Les deux lignes ne sont par contre pas identiques puisque seule ligneB1 est liée à ligneA.

    Mon problème est le suivant: j'update tableA grâce à:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    UPDATE tableA 
    SET champAUpdater = (
      SELECT tableB2.champ 
      FROM [...] 
      WHERE tableA.clef = tableB1.clef
    )
    Cela fonctionne mais l'update passe sur toutes les lignes (même s'il ne modifie que les bonnes) et les performances sont donc moyennes. Une solution semble être d'ajouter une condition where après le set en répétant la requête, mais ça n'est pas très élégant. Je pense qu'on peut aussi faire passer l'update sur un select limitant le nombre de lignes de tableA, mais ça reste ennuyeux de répéter deux fois la même requête.

    Si je n'ai pas trop mal exposé le problème, existe-t’il une solution qui permette d'updater directement les bonnes lignes de manière performante?

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Oui, quel est votre SGBD ?

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 144
    Points : 97
    Points
    97
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Oui, quel est votre SGBD ?
    Pardon je croyais être sur le forum Oracle, je me suis trompé! (Il s'agit donc d'oracle 11g).

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Dans ce cas vous pouvez utiliser MERGE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MERGE INTO tableA A
    USING (votre select B1 + B2) B
    ON (A.clef = B.clef)
    WHEN MATCHED THEN UPDATE
    SET A.champAUpdater = B.champ;

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 144
    Points : 97
    Points
    97
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Dans ce cas vous pouvez utiliser MERGE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MERGE INTO tableA A
    USING (votre select B1 + B2) B
    ON (A.clef = B.clef)
    WHEN MATCHED THEN UPDATE
    SET A.champAUpdater = B.champ;
    Excellente idée! J'utilise souvent des merges et j'y avait pas pensé du tout! Merci beaucoup.

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

Discussions similaires

  1. Valeur retournée depuis le Select : 6 au lieu de 06
    Par JackBeauregard dans le forum Langage
    Réponses: 4
    Dernier message: 14/01/2007, 20h35
  2. [Mysql 3.23] Un UPDATE avec un SELECT
    Par griese dans le forum Langage SQL
    Réponses: 8
    Dernier message: 25/12/2006, 09h09
  3. [MySQL] Update depuis un tableau
    Par psychoBob dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 07/01/2006, 14h53
  4. UPDATE SUR UN SELECT
    Par Alocer dans le forum Requêtes
    Réponses: 3
    Dernier message: 14/10/2005, 20h09
  5. [ SQL ] Faire un update avec un select imbriqué
    Par zozolh2 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 11/04/2005, 12h05

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