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 :

UPDATE Table Set Field = Select Count(*). Possible ?


Sujet :

Requêtes et SQL.

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 12
    Par défaut UPDATE Table Set Field = Select Count(*). Possible ?
    Bonjour,

    Comment renseigner le champ d'une table avec le nombre d'enregistrement d'une autre table ?

    J'essaye ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE Livres as livr SET livr.Cdes_An_Passé = (SELECT COUNT(*)   FROM Commandes WHERE Commandes.Livre_ID = livr.ID) ;
    Et j'obtiens ceci :
    "L'opération doit utiliser une requête qui peut être mise à jour"

    Alors que je suis Admin de la BdD et que les tables sont par ailleurs normalement accessibles en écriture.

    Est-ce que c'est possible sous Access? Il y a t-il une autre syntaxe ?
    Merci de vos réponses.

    Denis

  2. #2
    Membre Expert

    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
    Par défaut
    Bonsoir,

    Est-ce que Livres est une requête ?

    D'autre part, ton SQL a une erreur à l'intérieur de la sous requête où le champ livr.ID "tombe du ciel" !
    _

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 12
    Par défaut
    bonsoir, et merci de te pencher sur le pb.

    Livres est une table à laquelle j'attribue l'alias livr par le mot clé As

    donc, normalement, livr.ID est le champ ID de mon alias livr.

    Ce que j'essaye de faire, c'est de mettre à jour le champ Cdes_An_Passé de la table Livres avec le nombre de commandes (donc d'enregistrements) de la table Commande.

    Dans ma table Commande, j'ai un champ Livre_ID qui fait référence au champ ID de la table Livres.

    Toute syntaxe pour me permettre d'y arriver sera la bienvenue, parce que ça fait un moment que j'y suis, au point de me demander si c'est possible avec Access ?

    Denis

  4. #4
    Membre Expert

    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
    Par défaut
    Bonjour,
    Citation Envoyé par DocDen Voir le message

    Livres est une table à laquelle j'attribue l'alias livr par le mot clé As

    donc, normalement, livr.ID est le champ ID de mon alias livr.
    Effectivement, il n'y avait pas d'erreur, j'avais mal lu.
    Citation Envoyé par DocDen Voir le message

    Toute syntaxe pour me permettre d'y arriver sera la bienvenue, parce que ça fait un moment que j'y suis, au point de me demander si c'est possible avec Access ?
    Heureusement que tu es prêt à tout... parce que tu n'as pas le choix !
    Il te faut contourner le problème en utilisant la fonction de domaine DCount().
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UPDATE Livres as livr 
    SET livr.Cdes_An_Passé = DCount("*", "Commandes", "Livre_ID=" & livr.ID);

    Ton code SQL est pourtant correct, mais JET (le moteur de bases de données d'Access) souffre d'une très génante limitation:
    Les données d'une requête ne peuvent être mises à jour que si toutes les colonnes sont "modifiables".
    Or la sous-requête SELECT COUNT(*) est une aggrégation qui ne peut pas être modifiée.
    Bien sûr, nous savons que c'est sans importance puisqu'elle est placée du côté droit de l'affectation.
    Mais JET s'arrête là pour décréter que la requête n'est pas modifiable.

    En fait, je pense que JET travaille en 2 temps:
    (1) il construit une requête SELECT intermédiaire,
    (2) il applique les mises à jour dans le jeu de données provenant de cette requête..

    Dans le cas présent, la requête SELECT intermédiaires pourrait être:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT livr.*, 
        (SELECT COUNT(*)   FROM Commandes WHERE Commandes.Livre_ID = livr.ID) AS nCount 
    FROM Livres AS livr  ;
    Et le jeu de données retourné par cette requête SELECT intermédiaire n'est pas modifiable.

    Dommage.
    _

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 12
    Par défaut
    Merci beaucoup JBO pour tes explications.

    Je ne connaissais pas DCount.

    Si cela fonctionne bien dans Access même, mon programme VB (6...) qui utilise une connexion Jet OLEDB me renvoi l'erreur "Fonction DCount non définie dans l'expression".

    J'en ai été réduit à boucler sur mes enregistrement pour les mettre à jour en faisant un SELECT Count(*)... à chaque fois. Une misèèère.

    Mais au moins ça me permet d'avancer.

    Merci encore

    Denis

  6. #6
    Membre Expert

    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
    Par défaut
    Bonjour Denis,
    Citation Envoyé par DocDen Voir le message
    Je ne connaissais pas DCount.
    [...]

    Si cela fonctionne bien dans Access même, mon programme VB (6...) qui utilise une connexion Jet OLEDB me renvoi l'erreur "Fonction DCount non définie dans l'expression".
    C'est une des fonctions de domaine fournies pas Access et qui sont souvent utilisées dans les requêtes SQL d'Access pour pallier les petites misères comme celle que tu déplores. _

    Quand les bibliothèques DAO ou ADO sont exploitées dans le contexte d'Access, ces fonctions sont disponibles.
    Autrement, sans Access, cela provoque une erreur (forcément).

    Citation Envoyé par DocDen Voir le message

    J'en ai été réduit à boucler sur mes enregistrement pour les mettre à jour en faisant un SELECT Count(*)... à chaque fois. Une misèèère.
    Une autre approche consiste à utiliser 2 requêtes SQL.
    * une première pour remplir une table de travail avec les données agrégées (ici COUNT) et un champ identifiant;
    * une deuxième pour ensuite exécuter l'UPDATE en le basant sur une jointure entre la table à mettre à jour et la table de travail, avec le SET adapté en conséquence.

    Les performances s'en ressentent immédiatement par rapport à une boucle VBA sur un Recordset avec n exécutions de la requête SELECT COUNT(*) pour chacun des enregistrements parcourus.
    _

Discussions similaires

  1. Update machin Set x = select machine
    Par utan88 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 01/03/2011, 08h15
  2. UPDATE <table> SET <champ = valeur > IF NULL ?
    Par gelo91 dans le forum Requêtes
    Réponses: 5
    Dernier message: 04/03/2010, 16h28
  3. Select count avec jointure, en récupérant les 0 : possible ?
    Par littlewings dans le forum Requêtes
    Réponses: 2
    Dernier message: 17/07/2008, 12h57
  4. select count (*) sur 3 tables
    Par jbidou88 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 05/05/2008, 13h43
  5. update d'une table suivant un select d'une autre table
    Par cortex024 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 29/03/2007, 12h38

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