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 MySQL Discussion :

UPDATE multiples : un seul pris en compte


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 19
    Points : 16
    Points
    16
    Par défaut [RESOLU] UPDATE multiples : un seul pris en compte
    Bonjour,

    Le contexte de mon pb :
    J'ai une table comptes et une table operations.
    Lors du traitement des opérations :
    les comptes destinataires sont crédités du montant de chacune des opérations.

    Malheureusement, lorsque deux opérations ont le même destinataire, il semblerait que mon compte = compte + montant travaille toujours avec la valeur pré-UPDATE.
    En conséquence, une seule opération est créditée (la première d'après mes tests)

    Est-ce une limitation classique de MySQL ? (ma requête est un UPDATE multi-tables)

    N.B. Aucune erreur n'apparait ds phpMyAdmin, marlgré la différence entre la valeur attendue et la valeur trouvée ; de plus les deux opérations font bien partie du WHERE puisque mon UPDATE multi-table les "marque" aussi comme effectuées lors de cet UPDATE.

    Merci,
    b.

    P.S. pour les curieux et si ça peut vous servir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE operations, comptes
    SET op_state = '2', compte_montant = compte_montant + op_montant
    WHERE op_state = '1' AND compte_id = op_dest

  2. #2
    Membre actif Avatar de Ryan Sheckler
    Homme Profil pro
    Moine
    Inscrit en
    Novembre 2005
    Messages
    196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Moine

    Informations forums :
    Inscription : Novembre 2005
    Messages : 196
    Points : 216
    Points
    216
    Par défaut
    1- Quelle version de MySQL ?

    2- Es-tu sûr que op_montant est différent de NULL et différent de 0 ?

    3- Le câble est branché ? (désolé )

    Parce qu'en tous les cas, je viens de tester sur MySQL 5.0.16 un UPDATE multi-table et il n'y a eu aucun problème.

    D'ou je pense à ta version (ou bien à la valeur de op_montant).
    " Si un jour nocturne et un jour diurne pouvaient nous embrasser tous,
    ce serait le but suprême de tous les désirs. " [Schelling]

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 19
    Points : 16
    Points
    16
    Par défaut
    salut je teste en local avec le dernier EasyPHP, je ne pense pas que ce soit un pb de version.
    Comme expliqué précédemment, l'UPDATE se passe très bien, sans aucune erreur signalée ...
    Le pb se situe dans le "compte_montant = compte_montant + op_montant".

    Je me demande donc si dans une telle écriture la règle est : la valeur avant UPDATE sera augmentée de op_montant.
    Si c'est le cas, ce n'est pas ce que je souhaite, puisque cette "case" de ma table peut être updatée plusieurs fois au cours de cette même unique requête.

    Merci pour ta réponse, j'espère avoir été clair dans mes explications.
    b.

  4. #4
    Membre actif Avatar de Ryan Sheckler
    Homme Profil pro
    Moine
    Inscrit en
    Novembre 2005
    Messages
    196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Moine

    Informations forums :
    Inscription : Novembre 2005
    Messages : 196
    Points : 216
    Points
    216
    Par défaut
    J'ai testé sous MySQL 5.0.16 (au passage, easyphp, même dernière version, n'a sûrement pas la dernière version de mysql) sur un attribut de type integer.

    numero ou la valeur était de 1.
    j'ai lancé dans la requête update : numero = numero + 1.
    la valeur de numero était donc de 2.

    si je relance une requête : numero = numero +1.
    la valeur de numero sera de 3.

    au passage, ma requête modifiait la valeur d'un attribut d'une autre table, et il n'y a eu aucun problèmes d'aucun côté.

    Je ne sais pas si ça t'aide.
    " Si un jour nocturne et un jour diurne pouvaient nous embrasser tous,
    ce serait le but suprême de tous les désirs. " [Schelling]

  5. #5
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut Re: UPDATE multiples : un seul pris en compte
    J'ai déjà fait des UPDATE multi-table et ça marche très bien (mais il peut aussi y avoir un vieux bug qui traine...).

    Tu as essayé avec une jointure "INNER JOIN" et en spécifiant le nom de tes tables ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UPDATE operations op
    INNER JOIN comptes cpt ON (cpt.compte_id = op.op_dest)
     
    SET op.op_state = '2', cpt.compte_montant = cpt.compte_montant + op.op_montant
    WHERE op.op_state = '1'
    J'aime pas les jointures basées sur la clause WHERE pour tout un tas de raisons.
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 19
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    D'abord, je vous remercie pour vos réponses.

    Mikanou, j'ai pas du être assez clair sur le "en une seule requête" ... je confirme que avec plusieurs, ça marche bien

    pcaboche, je voulais essayer une jointure explicite après lecture de la doc MySQL et des réponses s'approchant le plus sur le forum ... mais assez nouveau dans le domaine, j'avais un peu de mal.

    J'ai testé ta méthode qui malheureusement donne le même résultat que la mienne.
    Pour info, avec un LEFT JOIN, une opération est prise en compte, avec RIGHT une autre ; ce qui tend à prouver qu'il s'agirait d'une limitation de mySQL (mais je peux me tromper).

    Enfin, en m'inspirant de ta requête, j'ai essayé de forcer l'index sur la table operations ... USE INDEX (op_id) => erreur "la clef n'existe pas dans la table" alors que c'est bien ma clef primaire ...

    Si vous avez d'autres pistes, ou si vous faites mieux que moi avec les pistes ci-dessus, je suis preneur
    Merci pour votre aide,
    b.

  7. #7
    Membre régulier
    Profil pro
    Administrateur de base de données
    Inscrit en
    Juillet 2003
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juillet 2003
    Messages : 94
    Points : 116
    Points
    116
    Par défaut
    Bonsoir,

    J'ai testé sur un jeu d'essais identique pour une version 4.1.8 avec exactement le même problème

    Cette syntaxe fonctionne et traite pour 1 compte donné TOUTES les OPERATIONS et non pas la 1ère trouvée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    update OPERATIONS, COMPTES,
    (
    select compte_id, SUM(op_montant) MTT
    from OPERATIONS, COMPTES
    WHERE OPERATIONS.op_state = '1'
    AND COMPTES.compte_id = OPERATIONS.op_dest
    group by compte_id
    ) TOT
    set COMPTES.compte_montant = COMPTES.compte_montant + TOT.MTT,
    OPERATIONS.op_state = '2'
    WHERE OPERATIONS.op_state = '1'
    AND COMPTES.compte_id = OPERATIONS.op_dest
    and COMPTES.compte_id = TOT.compte_id
    Cordialement

    Selecta

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 19
    Points : 16
    Points
    16
    Par défaut
    Je dois avouer que j'ai mis 10 min à comprendre ta requête

    Je suis rassuré que ce ne soit pas une limitation de SQL (j'avais un peu du mal à y croire ). Mais j'étais loin de penser qu'un SELECT pouvait être assimilé à une table.

    La meilleure solution que j'avais trouvée nécessitait 3 requêtes avec des sub-SELECT partout, et j'avais dû rajouter une colonne avec un hash pour m'assurer que cette opération ne pouvait etre effectuée qu'une seule fois ...

    Je te remercie grandement pour ton aide
    b.

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

Discussions similaires

  1. Seul le premier ID est pris en compte
    Par Stalk3R dans le forum jQuery
    Réponses: 19
    Dernier message: 02/07/2012, 10h31
  2. Réponses: 1
    Dernier message: 22/02/2010, 11h58
  3. Réponses: 3
    Dernier message: 16/12/2009, 11h41
  4. Réponses: 2
    Dernier message: 14/08/2009, 10h17
  5. Update non pris en compte!
    Par cseb73 dans le forum Requêtes
    Réponses: 9
    Dernier message: 29/06/2008, 15h34

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