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

Requêtes et SQL. Discussion :

Requete UPDATE avec sous-requete imbriquée


Sujet :

Requêtes et SQL.

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Requete UPDATE avec sous-requete imbriquée
    Bonjour,

    Dans MS ACCESS 2000 (je pense que la version n'a aucune importance)
    j'ai créé une nouvelle requête,
    je suis passé tout de suite en mode SQL,
    et j'ai tapé l'ordre SQL suivant :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    UPDATE FACTURES
    SET FACMNTPREC = (SELECT T2.FACMNT from FACTURES T2 where T2.FACNUM = FACNUM -1)
    WHERE FACNUM>1;

    ACCESS refuse de m'exécuter la requête et m'affiche le message suivant :

    Nom : ACCESS_MSG.jpg
Affichages : 5008
Taille : 10,9 Ko

    Pour info, le but de la requête UPDATE est de mettre à jour pour chaque facture (sauf la première),
    le champ FACMNTPREC (montant de la précédente facture) en allant chercher (avec la sous-requête),
    la valeur du champ FACMNT de l'entregistrement correspondant à la précédente facture (FACNUM - 1).

    Je précise que la structure et le contenu de ma table FACTURES sont tels
    que pour chaque enregistrement de ma requête principale,
    la sous-requête me ramène exactement un et un seul enregistrement,
    ce n'est donc pas de là que vient le problème.

    Je précise également que cet ordre SQL fonctionne parfaitement sous SQLServer ...

    Qu'est-ce qui ne plait pas au moteur MS ACCESS
    et comment lui faire exécuter un tel ordre pourtant assez basique.

    Merci de m'aider à résoudre ce pbm.
    Salutations.

  2. #2
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    correction de mon message ci-dessus : mal copié mon ordre SQL, il faut qualifier le champ de ma table principale dans ma sous-requete :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE FACTURES
    SET FACMNTPREC = (SELECT T2.FACMNT from FACTURES T2 where T2.FACNUM = FACTURES.FACNUM -1)
    WHERE FACNUM>1;

  3. #3
    Rédacteur/Modérateur

    Avatar de Jean-Philippe André
    Homme Profil pro
    Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Inscrit en
    Juillet 2007
    Messages
    14 642
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 14 642
    Points : 34 350
    Points
    34 350
    Par défaut
    salut,
    le = + select n'est pas idéal sous Access, d'autre part, il est plus judicieux de spécifier complètement le champs à mettre à jour :
    à essayer comme ceci :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE FACTURES INNER JOIN FACTURES T2 ON T2.FACNUM = FACTURES.FACNUM -1
    SET FACTURES.FACMNTPREC = T2.FACMNT
    WHERE FACTURES.FACNUM>1;

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Bonjour piou piou,
    merci de ton aide,

    oui l'ordre SQL avec jointure comme celui de ta réponse fonctionne.
    C'est ce que j'utilise depuis de nombreuses années dans ACCESS à chaque fois que le moteur refuse mes ordres avec sous-requête,
    mais cette fois-ci j'aimerais aller jusqu'au bout des choses et comprendre une fois pour toutes ce qui pose problème.

    Mordre SQL est tout à fait correct du point de vue SQL pur,
    par contre il doit y avoir quelquechose qui pose pbm au niveau de la syntaxe propre à ACCESS.

    J'ai encore simplifié mon ordre pour essayer de cerner le pbm :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE FACTURES SET FACMNTPREC = (select ch1 from TEST);

    avec TEST qui est une table à un seul champ (ch1) et un seul enregistrement, mais cet ordre ne fonctionne pas non plus !!!

    J'ai aussi essayé
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE FACTURES SET FACMNTPREC = (select Max(ch1) from TEST);
    pour qu'il ait la certitude que ma sous-requête ne retourne qu'un seul enregistrement, comme ce doit être le cas dans ce genre d'ordre,
    mais ça ne lui plait toujours pas.

    Par contre
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE FACTURES SET FACMNTPREC =7;
    fonctionne !

    ce n'est donc pas une question de table vérouillée, ou de màj interdite,
    ce doit être la syntaxe concernant l'emploi de sous-requête qui ne lui convient pas,
    c'est pourtant on ne peut plus simple !

    De plus son message "L'opération doit utiliser une requête qui peut être mise à jour" n'a pas de sens !
    C'est une table qui peut être mise à jour, mais pas une requête !!
    En tout cas le message n'est pas approprié puisque la màj peut se faire.

    Cette fois ci, je ne lâche pas l'affaire,
    l'exemple de la facture et du montant précédent étant un cas inventé pour illustrer mon pbm dans ce post, mais j'ai en réalité des cas plus complexes à solutionner et j'ai vraiment besoin d'utiliser des sous-requêtes dans des ordres UPDATE, comme on peut le faire partout ailleurs (SQLServer, Oracle ...)

    Je continue à chercher, sur d'autre sites aussi,
    merci d'avance si tu pouvais continuer aussi à m'aider ...
    ... à TROUVER ! ;-)

    A+

  5. #5
    Rédacteur/Modérateur

    Avatar de Jean-Philippe André
    Homme Profil pro
    Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Inscrit en
    Juillet 2007
    Messages
    14 642
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 14 642
    Points : 34 350
    Points
    34 350
    Par défaut
    Le est prohibé on dira

    soit tu utilises
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    MonChamp IN (SELECT MonChamp ...
    soit tu utilises une jointure dans tes requêtes
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE A 
    INNER JOIN B 
    ON A.champ1= B.Champ1 
    SET A.Champ2 = B.Champ2

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    1) le = (SELECT fonctionne pourtant dans le where d'un UPDATE,
    voir l'exemple suivant qui s'exécute parfaitement sous ACCESS :

    (il s'agit de diminuer de 10% le montant des factures pour lesquelles
    les commandes ont été passées après le 01/01/2009)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE FACTURES  SET  FACMNT = FACMNT*0.9
    WHERE FACCMDNUM >= (SELECT Min(CMDNUM) FROM CMDES WHERE CMDDATE >= #01/01/2009#)
    2) MonChamp IN (SELECT MonChamp ...
    peut convenir dans un WHERE mais ne convient pas pour faire la mise à jour,
    il faut absolument le signe =

    3) Malheureusement je ne peux pas faire ma mise à jour avec une jointure de ce type
    car ma sous-requête (dans mon cas réél) comporte un Max() et ACCESS n'en veut pas :-(

    Il me faut vraiment réussir à faire un SET champ = SELECT (
    pour faire ce que je veux ...
    ... si je veux améliorer ce que je fais actuellement à savoir
    utiliser une requête supplémentaire qui écrit dans une table intermédiaire.
    Pas satisfaisant du tout d'autant que ma requête est assez simple.

    merci quand même

    A+

    PS : comment utilser les balises pour mettre le code SQL dans le cadre
    comme vous l'avez corrigé sur mes précédents messages ?
    J'ai essayé le #, mais ça ne marchait pas en prévisualisation.

    je fais un test :

  7. #7
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour,
    Citation Envoyé par LVELVE Voir le message
    3) Malheureusement je ne peux pas faire ma mise à jour avec une jointure de ce type
    car ma sous-requête (dans mon cas réél) comporte un Max() et ACCESS n'en veut pas :-(

    Il me faut vraiment réussir à faire un SET champ = SELECT (
    pour faire ce que je veux ...
    ... si je veux améliorer ce que je fais actuellement à savoir
    utiliser une requête supplémentaire qui écrit dans une table intermédiaire.
    Pas satisfaisant du tout d'autant que ma requête est assez simple.
    On peut regretter que le moteur de bases de données d'Access ne soit pas plus performant et "conforme" aux standards SQL.
    Je te proposerai bien un contournement qui ne sera, hélas, pas portable, et pas optimisable par le moteur de bases de données.

    Il s'agit d'utiliser une fonction de domaine d'Access en lieu et place de la sous-requête, située côté droit de l'affectation.
    Et là tu pourrais par exemple utiliser DMax() qui équivaut au (SELECT MAX() ...) du SQL.

    Je te donne 2 exemples adaptés de tes précédents messages:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE FACTURES
    SET FACMNTPREC = DLookup("FACMNT", "FACTURES", "FACNUM = " & FACNUM -1)
    WHERE FACNUM>1;
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    UPDATE FACTURES SET FACMNTPREC = DMax("ch1", "TEST");

  8. #8
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 6
    Points : 10
    Points
    10
    Par défaut
    Bonjour à tous,

    Je me permet de déterrer ce vieux sujet car je viens de rencontrer le même problème.
    De toute façon, comme Access est éternel, mon idée pourra peut-être en aider quelques-uns.

    Donc, puisque le SQL d'Access ne supporte pas les requêtes imbriquées dans un UPDATE, l'idée est de remonter celles-ci directement dans la requête principale comme ceci :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE FACTURES T1, FACTURES T2
    SET T1.FACMNTPREC = T2.FACMNT
    WHERE (T2.FACNUM = (T1.FACNUM - 1))
     AND (T1.FACNUM > 1);

  9. #9
    Expert éminent sénior
    Avatar de tee_grandbois
    Homme Profil pro
    retraité
    Inscrit en
    Novembre 2004
    Messages
    8 769
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Novembre 2004
    Messages : 8 769
    Points : 14 810
    Points
    14 810
    Par défaut
    Bonsoir Fridorick,
    merci pour la solution proposée, elle est cependant similaire à celle donnée par Jean-Philippe André ici

Discussions similaires

  1. Requete update avec sous requete et max en jointure
    Par youyoupapayou dans le forum Langage SQL
    Réponses: 6
    Dernier message: 27/08/2009, 16h19
  2. MySQL: Probleme d'UPDATE avec sous requete SELECT
    Par simonius dans le forum Requêtes
    Réponses: 1
    Dernier message: 05/11/2007, 14h57
  3. Requete Update avec sous requete et jointure
    Par javaboy dans le forum Langage SQL
    Réponses: 2
    Dernier message: 09/05/2007, 11h03
  4. Requete Update avec sous requete
    Par joziel dans le forum Langage SQL
    Réponses: 7
    Dernier message: 28/08/2006, 15h15
  5. problème update avec sous requetes
    Par stoz dans le forum Langage SQL
    Réponses: 6
    Dernier message: 12/10/2005, 16h44

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