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 :

UPDATE à la con...


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Juillet 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 11
    Par défaut UPDATE à la con...
    Salut,

    Je cherche à mettre à jour une table. Cette table (Désordres-34) possède un champ NATURE_DU_PHENOMENE et un champ TYPE. Une autre table (Phénomènes) contient les memes champs (respectivement NATURE_PHENOMENE et ABBREVIATION qui en est la clé). La première table a été renseignée sans filtres de saisie ==> erreurs de saisies.
    D'où la nécessité de mettre à jour le champ de la 1e table avec le champ de la seconde. Mais avec la requete suivante, il ne se passe rien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE [Désordres-34] 
    SET [Désordres-34].NATURE_du_PHENOMENE = Phénomènes.NATURE_PHENOMENE
    WHERE [Désordres-34].NATURE_du_PHENOMENE <> Phénomènes.NATURE_PHENOMENE 
    AND Phénomènes.ABBREVIATION=[Désordres-34].TYPE;"
    Qu'est-ce qui cloche?

    Les enregistrements comportant des erreurs ont été extraits avec une requete dans uen liste. Serait-il possible d'utiliser le contenu de cette liste pour effectuer cette requete au lieu de mettre une clause WHERE sans fin?

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Question bête : tu as bien fait un COMMIT après l'exécution de tes requêtes UPDATE ?
    Si c'est le cas alors donne un extrait des tables Désordres-34 et Phénomènes pour que je visualise exactement la mise à jour que tu souhaites effectuer.

    D'autre part, j'imagine que l'on te l'a déjà fait remarquer mais il est fortement déconseillé d'utiliser des accents et autre caractères particuliers dans les noms de champs / tables.

  3. #3
    Membre habitué
    Inscrit en
    Juillet 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 11
    Par défaut
    J'ai trouvé pourquoi il ne fesait rien. J'avais oublié le DoCmd.RunSQL...
    Bon, maintenant, quand il éxécute la commande, il me demande la valeur de Phenomenes.NATURE_PHENOMENE. Le problème est que je veux qu'il prenne la valeur correspondante dans la table Phenomene.

    PS: je prend en compte ta remarque sur les accents et modifie le nom de la table...

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Je ne connais pas le SGBD sur lequel tu travailles (Access j'imagine) mais je pense que cette erreur vient du fait que tu as mal identifié Phenomenes.NATURE_PHENOMENE => fait attention à la casse, aux accents, etc. et du coup ton SGBD considère que c'est une valeur à saisir (je dis + ou - au hasard 8) )

  5. #5
    Membre habitué
    Inscrit en
    Juillet 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 11
    Par défaut
    Bon, étant donné que ça bloque sur la valeur de Phenomenes.NATURE_PHENOMENE, c'est le meme probleme que le topic
    SQl+update avec 2 Table.
    J'ai fait un essai mais la réponse lorsque je lance la commande est la meme.
    Voilà mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            SQL = "UPDATE [Désordres-34] " & _
                "SET [Désordres-34].NATURE_du_PHENOMENE = (SELECT Phenomenes.NATURE_PHENOMENE " & _
                                                            "FROM Phenomenes, [Désordres-34] " & _
                                                            "WHERE Phenomenes.ABBREVIATION=[Désordres-34].TYPE) " & _
                "Where [Désordres-34].NATURE_du_PHENOMENE <> Phenomenes.NATURE_PHENOMENE " & _
                "AND Phenomenes.ABBREVIATION=[Désordres-34].TYPE;"
    Pourquoi ai-je toujours la meme boite de dialogue me demandant la valeur de Phenomenes.NATURE_PHENOMENE?

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Normal que ta requête de mise à jour te demande de saisir des infos de la table Phenomenes ; tu trouveras plus d'explication sur les requêtes UPDATE ici http://sql.developpez.com/sqlaz/dml/#L3.5.

    D'autre part le fait qu'un de tes champs soit nommé TYPE peut te poser des problèmes (mais peut être pas ici) car c'est un mot réservé du langage SQL.

    Enfin, si la jointure entre tes tables Desordres-34 et Phenomenes se fait sur Phenomenes.ABBREVIATION=[Desordres-34].TYPE alors je te propose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    UPDATE [Desordres-34] 
    SET [Desordres-34].NATURE_du_PHENOMENE = ( SELECT Phenomenes.NATURE_PHENOMENE
                                               FROM [Desordres-34], Phenomenes
                                               WHERE [Desordres-34].NATURE_du_PHENOMENE <> Phenomenes.NATURE_PHENOMENE
                                               AND Phenomenes.ABBREVIATION=[Desordres-34].TYPE )
    WHERE EXISTS ( SELECT '+'
                   FROM [Desordres-34], Phenomenes
                   WHERE [Desordres-34].NATURE_du_PHENOMENE <> Phenomenes.NATURE_PHENOMENE
                   AND Phenomenes.ABBREVIATION=[Desordres-34].TYPE );

  7. #7
    Membre habitué
    Inscrit en
    Juillet 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 11
    Par défaut
    Quand je lance la requete que tu as corrigé, je reçois un message du débuggueur: "L'opérateur doit utiliser une requete qui peut etre mise à jour"
    Niarf?

    De plus, que veut dire:
    ?

  8. #8
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Le libellé du message d'erreur ne m'aide pas beaucoup (toi non plus j'imagine).
    Il est tout-à-fait possible que ma requête UPDATE soit fausse et pour savoir si le problème vient de là, tu peux remplacer cette requête UPDATE par une requête de mise à jour super simple (ie avec tes composants et ta configuration actuelle) ; si le message persiste alors l'erreur vient d'ailleurs.

    Concernant le '+' je l'utilise conjointement à la clause EXISTS qui fonctionne sur le principe que la sous-requête retourne ou non des données (http://sql.developpez.com/sqlaz/sousrequetes/#L1.5.1 ).
    Comme dans notre cas on se fiche de la nature des données retournées par la sous-requête (ce qui n'est pas le cas par exemple avec une clause IN par exemple) alors on demande à la sous-requête de retourner un élément bidon pour chaque enregistrement obtenu.

    Je viens de m'apercevoir que ma requête est incorrecte (mea culpa j'ai trop de mal avec ton problème ):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    UPDATE [Desordres-34] AS D
    SET D.NATURE_du_PHENOMENE = ( SELECT Phenomenes.NATURE_PHENOMENE 
                        FROM Phenomenes 
                        WHERE D.NATURE_du_PHENOMENE <> Phenomenes.NATURE_PHENOMENE 
                        AND Phenomenes.ABBREVIATION=D.TYPE ) 
    WHERE EXISTS ( SELECT '+' 
                   FROM Phenomenes 
                   WHERE D.NATURE_du_PHENOMENE <> Phenomenes.NATURE_PHENOMENE 
                   AND Phenomenes.ABBREVIATION=D.TYPE );
    Confirmes-moi que la jointure entre ces 2 tables se fait uniquement sur ces données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Phenomenes.ABBREVIATION=D.TYPE

  9. #9
    Membre habitué
    Inscrit en
    Juillet 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 11
    Par défaut
    Je confirme: Phenomenes.ABBREVIATION=D.TYPE (ABBREVIATION est l'identifiant de la table Phenomenes).

    Quant à l'essai avec une requete plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SQL = "UPDATE [Désordres-34] SET [Désordres-34].NATURE_du_PHENOMENE = 'BANZAI'"
    ==> Ca marche.
    C'est une histoire sans fin... (en tous cas, je te remercie de te pencher sur mon problème)

  10. #10
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Ok comme le UPDATE simplifié fonctionne alors ça vient de la requête elle-même.

    A mon avis j'ai pas tout saisi dans la mise à jour que tu souhaites effectué et surtout je me trompe en m'inspirant de la requête que tu proposais initialement.
    Quand tu dis
    La première table a été renseignée sans filtres de saisie ==> erreurs de saisies.
    Qu'est-ce que tu veux dire ? Ce qui m'intrigue c'est que dans les requêtes que je te propose je trimbale la condition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ]D.NATURE_du_PHENOMENE <> P.NATURE_PHENOMENE
    qui n'a surement aucune logique ici.

    Tu peux donner un extrait de tes 2 tables AVANT mise à jour et un extrait de ce qui devrait avoir changé APRES mise à jour ?

  11. #11
    Membre habitué
    Inscrit en
    Juillet 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 11
    Par défaut
    TABLE1: Phenomenes
    ABBREVIATION(ID) NATURE_PHENOMENE
    E EBOULEMENT
    G GLISSEMENT DE TERRAIN

    TABLE2: Désordres:

    (Avant modification)
    ID TYPE NATURE_du_PHENOMENE
    3412201 E EBOULMENTS
    3412202 G GLISSEMNT TERRAIN

    (Après modification)
    ID TYPE NATURE_du_PHENOMENE
    3412201 E EBOULEMENT
    3412202 G GLISSEMENT DE TERRAIN

    La relation entre les deux tables se faisant avec les champs TYPE et ABBREVIATION. Le but étant de corriger les fautes de saisie.
    (je sais que j'aurai pu virer le champ NATURE_du_PHENOMENE mais mon chef ne m'a pas donné le choix...)

  12. #12
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    C'est très clair, donc avec cette requête on doit progresser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE [Desordres-34] AS D 
    SET D.NATURE_du_PHENOMENE = ( SELECT Phenomenes.NATURE_PHENOMENE 
                                  FROM Phenomenes 
                                  WHERE Phenomenes.ABBREVIATION = D.TYPE )

  13. #13
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 998
    Billets dans le blog
    6
    Par défaut
    Tu n'as toujours pas indiqué le SGBDR avec lequel tu travailles.

    mais en SQL normatif, la requête s'écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    UPDATE Desordres_34
    SET    NATURE_du_PHENOMENE = ( SELECT P.NATURE_PHENOMENE
                                   FROM   Desordres_34 D
                                          INNER JOIN Phenomenes P  
                                                ON D."TYPE" = P.ABBREVIATION)
    Plusieurs remarques :
    1) l'utilisation d'autres caractères que les 26 lettres de l'alphabet (sans diacritiques) des 10 chiffres et du blanc souligné dans les noms d'objet est à proscrire : http://sqlpro.developpez.com/cours/sqlaz/erreurs/#L1

    2) il est interdit de mettre des alias dans les tables cibles des mise à jour (INSERT, UPDATE, DELETE).

    Comme je suppose que c'est du SQL Server, ce dernier accepte une syntaxe plus spécifique que voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UPDATE Desordres_34
    SET    NATURE_du_PHENOMENE = P.NATURE_PHENOMENE
    FROM   Desordres_34 D
           INNER JOIN Phenomenes P  
                 ON D."TYPE" = P.ABBREVIATION
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  14. #14
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Ce n'est pas que je veuille remettre en cause tes affirmations SQLpro 8) mais je ne comprends pas pourquoi on ne peut pas utiliser d'alias dans une requête UPDATE par exemple ?

    J'ai effectué cette requête depuis IBExpert sur une base Interbase 6 et elle passe sans problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UPDATE CB_TMP CB
    SET CB.CB_NUMERO = ( SELECT CARTE.CB_NUMERO
                         FROM CARTE_BANCAIRE CARTE
                         WHERE CB.CB_CODRESA = CARTE.CB_CODRESA
                         AND CB.CB_NOENREG = CARTE.CB_NOENREG );
    Remarques :
    1/ je n'ai pas utilisé de INNER JOIN exprès dans la sous-requête car cela m'indique une erreur au niveau du JOIN "Table unknown CB"
    2/ le fait que les tables CB_TMP et CARTE_BANCAIRE aient exactement la même structure ne doit avoir aucune incidence sur le fait que cette requête fonctionne ?
    3/ Pourquoi cette requête fonctionne-t'elle ?
    4/ A quel(s) risque(s) je m'expose avec une telle syntaxe ?

  15. #15
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 998
    Billets dans le blog
    6
    Par défaut
    je te propose de formuler ta remarque directement au comité de normalisation ISO pour la norme SQL !!!

    C'est comme ça. POINT ! Pas d'alias dans les tables cibles des ordres de mise à jour.

    La raison est claire : on ne peut pas mettre plusieurs table comme cible pour un INSERT un DELETE ou un UPDATE. Donc comme il n'y a pas d'ambiguité possible, un alias ne sevirait à rien. Pire, il introduirait la confusion !

    En revanche tu peut mettre un alias pour chacune des tables figurant dans la sous requête. DONC :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    UPDATE CB_TMP
    SET    CB_NUMERO = CARTE.CB_NUMERO
    FROM   CB_TMP CB
           INNER JOIN CARTE_BANCAIRE CARTE
                 ON CB.CB_CODRESA = CARTE.CB_CODRESA
                    AND CB.CB_NOENREG = CARTE.CB_NOENREG
    Il serait temps d'apprendre SQL !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  16. #16
    Membre Expert

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Il serait temps d'apprendre SQL !
    Pas besoin d'être aussi sec je ne remettais pas en cause tes explications mais je trouve juste surprenant que cette syntaxe soit tolérée si elle risque d'introduire des confusions.

    Merci pour ces explications.

  17. #17
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 998
    Billets dans le blog
    6
    Par défaut
    Il y a un certains nombre d'éditeurs de SGBDR qui refusent d'appliquer la norme :
    soit parce que techniquement ils ne savent pas faire exemple MySQL.
    soit parce qu'ils ont un passé et se mettent très tardivement à le faire par exemple oracle.

    mais le respect de la norme est quelque chose d'important car la norme est faite par des gens intelligents, puisque ce sont les fabriquants de SGBDR eux mêmes !

    Mieux vaut donc la connaître que d'apprendre les spécificité de tel ou tel outiil !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. Requête update à partir d'une autre table
    Par amiral thrawn dans le forum Langage SQL
    Réponses: 5
    Dernier message: 15/02/2024, 11h40
  2. Pb d'update dans une DataGrid
    Par bidson dans le forum XMLRAD
    Réponses: 11
    Dernier message: 27/05/2003, 14h11
  3. [dBase]il y a mieux que la commande sql UPDATE ?
    Par sana72 dans le forum Autres SGBD
    Réponses: 4
    Dernier message: 12/12/2002, 11h59
  4. Réponses: 3
    Dernier message: 10/11/2002, 11h03
  5. update et virgule
    Par Delph dans le forum Bases de données
    Réponses: 8
    Dernier message: 27/08/2002, 14h40

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