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

MS SQL Server Discussion :

Remplir une colonne d'une table du résultat d'une SELECT


Sujet :

MS SQL Server

  1. #1
    Membre actif
    Inscrit en
    Octobre 2007
    Messages
    236
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Octobre 2007
    Messages : 236
    Points : 233
    Points
    233
    Par défaut Remplir une colonne d'une table du résultat d'une SELECT
    Salut,
    ça fait des jours que je cherche une solution pour remplir une colonne d'une table DevisList.TTC à partir du résultat d'une requête SELECT qui retourne plusieurs lignes. La solution que j'ai trouvé qui n'affiche pas un message d'erreur est la suivante mais ne fait rien car je reçois le message (0 lignes affectés)!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UPDATE DevisList
    SET TTC = (
    			SELECT SUM(Opération.Montant)
    			FROM Devis, Opération, DevisLink
    			WHERE Devis.ID = DevisLink.DevisID AND DevisLink.OpérationID = Opération.ID
    			GROUP BY Devis.ID
    )
    WHERE DevisList.TTC = NULL
    PS : Dans ma db j'ai une table Devis liée avec les Opération effectuées pour les clients à l'aide de recs d'une autre table DevisLink dont les champs (ID, DevisID et OpérationID).

    Merci d'avance...

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 737
    Points
    52 737
    Billets dans le blog
    5
    Par défaut
    Que d'horreur dans ce code... Ou avez vous appris le SQL ? ... Avez vous appris à modéliser une base de données ???

    Alors on commence :

    1) les noms des objets SQL (table, colonne, procédures, vue, fonction, contraintes...) ne doivent comporter que des lettres sans accents ni caractères diacritiques ou des chiffres ou encore le blanc souligné. Tout autre caractères est formellement interdit. Néanmoins certains SGBDR permettent d'utiliser d'autres caractères au risque de rendre impossible l'interopérabilité aves les programmes clients. Exemple : table "Opération".
    Lisez ce que j'ai écrit à ce sujet : http://sqlpro.developpez.com/cours/s...age=partie1#L1

    2) les jointures se font à l'aide de JOIN. Les jointures dans le WHERE sont une absurdité dont la syntaxe est obsolète depuis plus de 15 ans !
    Lisez les articles que j'ai écrit à ce sujet :
    http://sqlpro.developpez.com/cours/s...intures/#LII-B
    http://blog.developpez.com/sqlpro?ti..._dans_le_from_
    Voici comment devrait être récrite votre requête interne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT SUM(Opération.Montant)
    FROM   Devis AS D
           INNER JOIN DevisLink AS DL
                 ON D.ID = DL.DevisID
           INNER JOIN Operation AS O
                 ON DL.OpérationID = On.ID
    GROUP  BY D.ID
    3) dans un système d'information, une information doit être référencée par un nom unique. Or dans votre table, l'information de clef de devis s'apelle ID dans la table devis et devis ID dans la table DevisLink, en effet ces colonnes sont censées contenir les même informations pour la mise en relation et devraient donc porter le même nom. Si vous aviez utilisé un outil de modélisation, ou encore que vous aviez pensé votre modèle au niveau conceptuel, cette faute stupide aurait été évitée. Ceci est d'autant plus navrant qu'il apparait que vous avez d'autres colonnes nommées ID dans d'autres tables et qui contiennent des données différentes !
    Que se passera t-il le jour ou vous voudrez faire du NATURAL JOIN ??? Vous joindrez des carottes à des navets !

    4) le prédicat :
    WHERE DevisList.TTC = NULL
    vous donnera toujours faux... Par principe un marqueur NULL ne peut être comparé. pouvez-vous comparer une couleur qui n'existe pas à une autre qui n'existe pas non plus ? Donc NULL = NULL donne toujours UNKNOWN et se comporte comme faux !
    En revanche il existe des opérateurs spécialisés dans le traitement des marqueur NULL (NULL n'étant pas une valeur, mais justement l'ABSENCE DE VALEUR !).
    Lisez l'article que j'ai écrit à ce sujet : http://sqlpro.developpez.com/cours/null/

    5) erreur d'affectation :
    De plus ce prédicat WHERE, s'il marchait, fait en sorte que vous affectez à toutes les commandes dans lesquelles la colonne TTC est vide le même calcul, ce qui est absurde. il faut corréler la sous requête avec la table cible de l'ordre de mise à jour.

    6) données calculées
    En sus, il est totalement déconseillé de stocker les données calculées. Que ferez vous si une des données est modifiée ? Vous allez avoir stocké un calcul qui est faux !!!
    Parmi les principes fondamentaux des SGBDR, la non redondance est la règle : l'information ne doit se situer qu'à un seul endroit dans la base et par conséquent, ne jamais stocker de données qui peuvent être calculées.
    En revanche, si vous voulez "voir" votre calcul, rien de plus simple : il suffit de faire la requête et mieux, de l'encapsuler dans une vue (c'est fait pour cela les vues...).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE VIEW V_Devis
    AS
    SELECT D.ID, SUM(Opération.Montant) AS TTC, ???
    FROM   Devis AS D
           INNER JOIN DevisLink AS DL
                 ON D.ID = DL.DevisID
           INNER JOIN Operation AS O
                 ON DL.OpérationID = On.ID
    GROUP  BY D.ID, ???
    Ou ??? représente les autres colonnes de table Devis.

    7) correction
    enfin, si vous n'avez rien compris au SGBD relationnel et que vous voulez persister dans votre erreur, la requête correcte pour votre calcul redondant est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    UPDATE DevisList
    SET TTC = SUM(O.Montant)
    FROM   DevisList AS DLT
           INNER JOIN Devis AS D
                 ON DLT.??? = D.???
           INNER JOIN DevisLink AS DL
                 ON D.ID = DL.DevisID
           INNER JOIN Operation AS O
                 ON DL.OpérationID = On.ID
    GROUP  BY D.ID
    Et comme pour couronner le tout, vous n'avez pas respecter la charte de postage de ce forum, il est impossible de vous fournir le code exact. Merci donc de la lire : http://www.developpez.net/forums/d96...vement-poster/
    Et de la respecter intégralement pour vos futures demandes !

    Je pense que vous avez besoin de vous former sur SQL et les concepts des bases de données relationnelles. Mes livres, comme mon site web, peuvent vous y aider...

    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/ * * * * *

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 05/01/2010, 08h22
  2. Réponses: 3
    Dernier message: 06/11/2006, 08h14
  3. [sql 2005]: changer le nom d'une colonne dans un table
    Par TheLittle dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 12/06/2006, 15h29
  4. Insérer le rsultat d'une requète dans un table
    Par MadMarc dans le forum Access
    Réponses: 4
    Dernier message: 25/01/2006, 12h09
  5. Renommer une colonne avec ALTER TABLE...
    Par David.V dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 01/07/2004, 10h33

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