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

Langage SQL Discussion :

Requete Update compliquée


Sujet :

Langage SQL

  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 Requete Update compliquée
    Bonjour,

    Je cherche à mettre à jour une table en utilisant le résultat d'un select.

    Je m'explique:

    1) J'ai une requête de type select , qui renvoie deux clés et deux colonnes de type date pour une population ciblée (avoir une date de fin ). Ce select est sur une table A. ->
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select idPersonne, idSociete, dateDebut, dateFin 
    from tableA 
    where dateFin is not null
    2) Je dois mettre à jour les dates de la table B , pour l'enregistrement correspondant à idPersonne,idSociete de la table A

    Quelqu'un a une idée sur la facon de construire la requete ?

    Merci de votre aide.

  2. #2
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Principe général :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    UPDATE laTable
    INNER JOIN (
      SELECT lesColonnes
      FROM uneAutreTable
      WHERE restriction
    ) AS tmp ON condition_jointure_entre_laTable_et_uneAutreTable
    SET laTable.colonne = tmp.colonne
    Dans ton exemple, ça pourrait donner ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    UPDATE tableB
    INNER JOIN (
      SELECT idPersonne, idSociete, dateDebut, dateFin 
      FROM tableA 
      WHERE dateFin IS NOT NULL
    ) AS tmp ON tableB.dateDebut = tmp.dateDebut
    SET tableB.dateFin = tmp.dateFin

  3. #3
    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
    j'ai quelques soucis , voici ma requete:

    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
     
    Update AFXHISTSTAGE
    INNER JOIN(
    select  to_char(epi.episode_pk) as dim_value, 
            to_char(ae6.contact_id) as contact_id,
            nvl(to_number(sta.codacco), 0) as duree,
            sta.DTDEBUT2 as dateDebut,
            sta.DTFIN2 as dateFin
    From    referentiel.collecte_stages sta
    INNER JOIN   referentiel.collecte_etudiant etu on etu.noordre= sta.noordre
    INNER JOIN   agresso.aemstudent stu on stu.student_no= etu.codcuo2 and     stu.client='P1'
    INNER JOIN   agresso.aemepisode epi on stu.student_pk = epi.student_fk and epi.client='P1' and epi.status!='T' 
    INNER JOIN   referentiel.rep_ae6contact_org ae6 on STA.ABRENT=AE6.ACRONYM  AND AE6.ATTRIBUTE_ID = 'JC02' AND AE6.CLIENT = 'P1' AND AE6.CONTACT_CATEGORY = 'ENTREPRISE'
    INNER JOIN   agresso.afxhiststage afx ON (afx.dim_value=to_char(epi.episode_pk) and afx.contact_id=to_char(ae6.contact_id))
    Where sta.DTFIN2 is not null) AS tmp ON (AFXHISTSTAGE.DIM_VALUE=tmp.dim_value and AFXHISTSTAGE.CONTACT_ID=tmp.contact_id and AFXHISTSTAGE.NB_SEMAINES=tmp.duree)
    set AFXHISTSTAGE.DATE_DEBUT_2 =tmp.dateDebut, AFXHISTSTAGE.DATE_FIN_2= tmp.dateFin
    j'ai une erreur : mot clé SET absent


    Pour info je suis sous oracle 10G

  4. #4
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Je vois la fonction nvl. C'est Oracle non ?

    As-tu essayé ton SELECT en séparant les conditions de jointure et les conditions de restriction ? Comme tu n'as pas de jointure externe, ça devrait donner un résultat équivalent, voire meilleur.

    Ça donnerait ça :
    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
    UPDATE AFXHISTSTAGE
    INNER JOIN(
      SELECT to_char(epi.episode_pk) AS dim_value, 
        to_char(ae6.contact_id) AS contact_id,
        nvl(to_number(sta.codacco), 0) AS duree,
        sta.DTDEBUT2 AS dateDebut,
        sta.DTFIN2 AS dateFin
      FROM referentiel.collecte_stages sta
      INNER JOIN referentiel.rep_ae6contact_org ae6 ON sta.ABRENT = ae6.ACRONYM  
      INNER JOIN referentiel.collecte_etudiant etu ON etu.noordre = sta.noordre
        INNER JOIN agresso.aemstudent stu ON stu.student_no = etu.codcuo2 
          INNER JOIN agresso.aemepisode epi ON stu.student_pk = epi.student_fk 
        INNER JOIN agresso.afxhiststage afx ON afx.dim_value = to_char(epi.episode_pk) 
          AND afx.contact_id = to_char(ae6.contact_id))
      WHERE sta.DTFIN2 IS NOT NULL
        AND stu.client = 'P1'
        AND epi.client = 'P1' 
        AND epi.STATUS != 'T' 
        AND AE6.ATTRIBUTE_ID = 'JC02' 
        AND AE6.CLIENT = 'P1' 
        AND AE6.CONTACT_CATEGORY = 'ENTREPRISE'
    ) AS tmp ON 
      AFXHISTSTAGE.DIM_VALUE = tmp.dim_value 
      AND AFXHISTSTAGE.CONTACT_ID = tmp.contact_id 
      AND AFXHISTSTAGE.NB_SEMAINES = tmp.duree
    SET AFXHISTSTAGE.DATE_DEBUT_2 = tmp.dateDebut, 
      AFXHISTSTAGE.DATE_FIN_2 = tmp.dateFin
    Tu as une condition de jointure qui porte sur deux tables :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INNER JOIN agresso.afxhiststage afx ON afx.dim_value = to_char(epi.episode_pk) 
          AND afx.contact_id = to_char(ae6.contact_id))
    J'ai l'impression que tu as une boucle de jointures :
    sta => etu => stu => epi => afx => ae6 => sta
    |-----------------------------------------------------------------|

    La dernière est-elle vraiment utile ?

    Les fonctions to_char et compagnie dans la requête et surtout dans les conditions de jointure, c'est pas optimisé ! Problème de conception peut-être !

    Par contre ton message d'erreur est bizarre puisque le SET est bien présent !

  5. #5
    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
    Utilisez MERGE.

  6. #6
    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
    je suis parti d'une requete copiée/collée , pour le principe donc elle ne ressemble pas à grand chose ....

    malgré tout j'ai toujours la même erreur

    la notion de merge permet de faire de l'insert ou update en même temps non ?
    je conceptualise mal comment cela peut m'aider.

    merci de votre aide

  7. #7
    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
    Vous pouvez ne faire que l'update !
    Je vous laisse adapter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MERGE INTO t1
    USING (<votre select>) t2
       ON (t2.id = t1.id)
     WHEN MATCHED THEN UPDATE
      SET t1.col1 = t2.col1;

  8. #8
    Membre confirmé Avatar de juvamine
    Profil pro
    Chef de projet MOA
    Inscrit en
    Mai 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mai 2004
    Messages : 414
    Points : 502
    Points
    502
    Par défaut
    la syntaxe est
    UPDATE Table
    SET ...
    [FROM ... INNER JOIN...]

    ça donne donc

    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
    UPDATE AFXHISTSTAGE
    SET AFXHISTSTAGE.DATE_DEBUT_2 = tmp.dateDebut, 
      AFXHISTSTAGE.DATE_FIN_2 = tmp.dateFin
    FROM AFXHISTSTAGE
    INNER JOIN(
      SELECT to_char(epi.episode_pk) AS dim_value, 
        to_char(ae6.contact_id) AS contact_id,
        nvl(to_number(sta.codacco), 0) AS duree,
        sta.DTDEBUT2 AS dateDebut,
        sta.DTFIN2 AS dateFin
      FROM referentiel.collecte_stages sta
      INNER JOIN referentiel.rep_ae6contact_org ae6 ON sta.ABRENT = ae6.ACRONYM  
      INNER JOIN referentiel.collecte_etudiant etu ON etu.noordre = sta.noordre
        INNER JOIN agresso.aemstudent stu ON stu.student_no = etu.codcuo2 
          INNER JOIN agresso.aemepisode epi ON stu.student_pk = epi.student_fk 
        INNER JOIN agresso.afxhiststage afx ON afx.dim_value = to_char(epi.episode_pk) 
          AND afx.contact_id = to_char(ae6.contact_id))
      WHERE sta.DTFIN2 IS NOT NULL
        AND stu.client = 'P1'
        AND epi.client = 'P1' 
        AND epi.STATUS != 'T' 
        AND AE6.ATTRIBUTE_ID = 'JC02' 
        AND AE6.CLIENT = 'P1' 
        AND AE6.CONTACT_CATEGORY = 'ENTREPRISE'
    ) AS tmp ON 
      AFXHISTSTAGE.DIM_VALUE = tmp.dim_value 
      AND AFXHISTSTAGE.CONTACT_ID = tmp.contact_id 
      AND AFXHISTSTAGE.NB_SEMAINES = tmp.duree

  9. #9
    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
    Merci de votre aide.

    Pour le merge tout est la:
    http://oracle.developpez.com/faq/?page=3-1

    Ce qui donne (pour le principe car la requete n'est pas optimum)

    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 Agresso.AFXHISTSTAGE afx
      Using (SELECT epi.episode_pk AS dim_value, 
                    ae6.contact_id AS contact_id,
                    nvl(to_number(sta.codacco), 0) AS duree,
                    sta.DTDEBUT2 AS dateDebut,
                    sta.DTFIN2 AS dateFin
                  FROM referentiel.collecte_stages sta
                  INNER JOIN referentiel.rep_ae6contact_org ae6 ON sta.ABRENT = ae6.ACRONYM  
                  INNER JOIN referentiel.collecte_etudiant etu ON etu.noordre = sta.noordre
                  INNER JOIN agresso.aemstudent stu ON stu.student_no = etu.codcuo2 
                  INNER JOIN agresso.aemepisode epi ON stu.student_pk = epi.student_fk 
                  WHERE sta.DTFIN2 IS NOT NULL
                    AND stu.client = 'P1'
                    AND epi.client = 'P1' 
                    AND epi.STATUS != 'T' 
                    AND AE6.ATTRIBUTE_ID = 'JC02' 
                    AND AE6.CLIENT = 'P1' 
                    AND AE6.CONTACT_CATEGORY = 'ENTREPRISE') tmp
      ON  (to_char(afx.DIM_VALUE) = tmp.dim_value   AND to_char(afx.CONTACT_ID) = to_char(tmp.contact_id) AND afx.NB_SEMAINES = tmp.duree )
    WHEN MATCHED THEN -- Si Vraie
      Update set afx.DATE_DEBUT_2 = tmp.dateDebut, afx.DATE_FIN_2 = tmp.dateFin

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

Discussions similaires

  1. Requete UPDATE !!!
    Par fages dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 01/07/2004, 17h52
  2. [SYBASE] optimisation requete UPDATE
    Par metheorn dans le forum Sybase
    Réponses: 8
    Dernier message: 24/05/2004, 18h01
  3. [version] Requete Update avec différentes versions de mySQL
    Par regbegpower dans le forum Requêtes
    Réponses: 2
    Dernier message: 26/01/2004, 18h19
  4. Requete update
    Par gianfare dans le forum Langage SQL
    Réponses: 7
    Dernier message: 10/10/2003, 10h04
  5. [debutante] erreur requete update
    Par LineLe dans le forum ASP
    Réponses: 5
    Dernier message: 12/09/2003, 14h05

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