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 :

SQL SERVER 2000 - Vue dangereuse


Sujet :

MS SQL Server

  1. #1
    Membre régulier
    Inscrit en
    Décembre 2004
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 112
    Points : 94
    Points
    94
    Par défaut SQL SERVER 2000 - Vue dangereuse
    Bonjour tout le monde,

    je travaille sur un MS SQL 2000, et je viens de decouvrir un phénomène aussi interessant que dangereux!
    Je suis certain que d'autres ont eu le meme problème mais moi je n'aurais jamais imaginé un truc pareil.

    le probleme est le suivant:
    - on a une TABLE qui ressemble à ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Col_A   Col_B   Col_C   Col_D
    A1      B1      C1      D1
    A2      B2      C2      D2
    ...     ...     ...     ...
    et on en fait une VUE qui ressemble a ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Col_A   Col_B   Col_C
    A1      B1      C1      
    A2      B2      C2
    -Si je decide de changer l'ordre des colonnes dans TABLE, au lieu de:
    Col_A
    Col_B
    Col_C
    Col_D
    on a l'ordre suivant:
    Col_A
    Col_B
    Col_D
    Col_C

    TABLE aura l'air comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Col_A   Col_B   Col_D   Col_C
    A1      B1      D1      C1
    A2      B2      D2      C2
    ...     ...     ...     ...
    mais VUE ressemblera à ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Col_A   Col_B   Col_C
    A1      B1      D1      
    A2      B2      D2      
    !?!?!?!?!
    bien entendu le meme probleme peut etre generé si on supprime des colonnes de TABLE...
    Pour que la vue prenne la nouvelle structure, il faut qu'elle soit reexecuté et sauvgardé... ce que moi personnelement je fais qu'une fois lors de la creation de la vue, oubien s'il faut modifier quelque chose dans la vue...

    Donc utiliser des vues pour des processus automatisé risque d'etre dangereux...

    Est ce que ce truc est deja connu chez vous les professionnels de SQL Server?
    Est ce que c'est juste dans SQL 2000 que ceci peut se produire?

    Merci de partager ce que vous en pensez!

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 056
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 056
    Points : 1 216
    Points
    1 216
    Par défaut
    bonjour,

    C'est bien le fonctionnement normal. Vous avez la possibilité de créer vos vues avec l'option SCHEMABINDING qui empêchera toute modif sur les tables sous-jacentes d'une vue (il faudra alors la dropper puis la recréer).

    Sinon, pour prendre en compte les modifs de structure dans une table sous-jacente :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sp_refreshview <nom de la vue>
    Emmanuel T.

  3. #3
    Membre expert
    Avatar de cavo789
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2004
    Messages
    1 781
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 781
    Points : 3 034
    Points
    3 034
    Par défaut
    Un truc m'échappe:

    Si ta table Clients est composée des champs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Numéro Client     Nom    Prénom    Adresse
    et ta vue

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT [Numéro Client], Nom, [Prénom], Adresse FROM Clients

    Je ne comprends pas du tout pourquoi si tu changes l'ordre des champs dans la table (quoique là aussi je ne comprends pas le but de la manoeuvre vu que "l'ordre" n'a pas de sens dans un schéma d'une db), cet "ordre" impacterait ta vue.

    Ton SELECT fait référence au nom des champs; pas à leur position. La valeur du champs Adresse restera une adresse.

    Y'à vraiment un truc que j'ai pas pigé.
    Christophe (cavo789)
    Mon blog, on y parle Docker, PHP, WSL, Markdown et plein d'autres choses : https://www.avonture.be

  4. #4
    Membre régulier
    Inscrit en
    Décembre 2004
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 112
    Points : 94
    Points
    94
    Par défaut
    Citation Envoyé par kagemaru Voir le message
    ...C'est bien le fonctionnement normal...
    Merci kagemaru.
    si c'est le fonctionnement normal des vues, ca m'a couté quelques jours pour
    comprendre la source de quelques problemes tres serieux surevenu à cause de ca...

    Voici le cas reel:

    j'ai une table Participant qui doit permettre l'existance de doublons...
    ces doublons ont malheureusement des ID differents(numero de participant)
    concretement: un participant peut avoir 2 comptes avec 2 ID mais un des deux comptes a le status Actif, l'autre est Passiv.
    Il existe dans ma table Participant une autre colonne ID_Europeen qui a la meme valeurs chez le participant (Actif et Passiv).

    Là j'utilise 2 vues:
    -Vue_Actif:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select * from Participant where Actif=1
    -Vue_Passiv:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select * from Participant where Actif=0
    Plus loin dans mon programme je fais la joiture suivante pour trouver les participant double pour pouvoir transferer tout ce qui a été enregistré du compte Passiv au compte Actif:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Select * from 
    Vue_Actif inner join Vue_Passiv
    on Vue_Actif.ID_Europeen=Vue_Passiv.ID_Europeen
    le malheur est arrivé quand la structure de la table Participant a été modifié. du coup la colonne ID_Europeen dans mes vues pointe vers une autre colonne qui par hasard est une date d'enregistrement...
    et voila que la jointure me retourne des combinaison avec la date au lieu du ID_Europeen ce qui me donne des participants tout à fait differents des doubles que je cherche...
    vous imaginer le reste... des commandes ont été transferé à des Participant qui n'ont jamais rien commandé, au lieu de les transferer au nouveau compte des Participant (qui ont 2 comptes Actif/Passiv)


    J'espere que cette explication est claire pour toi cavo789...

    Si seulement je savais que ceci se passe comme ca, j'aurais fait en sorte de rafraichir mes vues chaque fois que je les appele

    ...

    Pour ceux qui vont me conseiller de travailler avec des ID unique pour les participants... ca peut pas marcher pour des raisons politiques

    Merci!

  5. #5
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Bonjour !
    Je suis aussi perplexe que Cavo.

    Normalement, une vue est définie par : (par exemple)
    CREATE VIEW mavue
    AS
    SELECT COL1 as C1, COL2 as C2, COL4 as C4
    FROM tableref

    Donc, si la COL3 disparait, où si l'ordre des colonnes de tableref change, ça ne change rien, non ?
    Jusque là, je pensais qu'une vue simple était simplement un alias sur une requête réinterprétée à chaque appel.

    Peux-tu donner le script de création de ta vue ?

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  6. #6
    Membre régulier
    Inscrit en
    Décembre 2004
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 112
    Points : 94
    Points
    94
    Par défaut
    Salut,

    la vue est crée comme dit plus haut:
    select * from participant where actif=1


    Je ne defini pas de colonnes specifiques car la vue est utilisé dans plusieurs endroit, pour plusieur raisons...
    donc pour eviter de taper certaines conditions dans mes requetes, j'utilise une vue qui elle contient deja des conditions...

    Merci!

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    265
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 265
    Points : 314
    Points
    314
    Par défaut
    Le "SELECT *" c'est à bannir des pratiques de développement... c'est ce qu'on essaye de te dire, référence explicitement les champs dans ta vue et cela t'évitera de mauvaises surprises.

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 848
    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 848
    Points : 52 964
    Points
    52 964
    Billets dans le blog
    6
    Par défaut
    Encore une fois il n'existe AUCUN ORDRE pré établis dans les bases de données : par d'ordre des colonnes, ni ordre des tables, ni aucun ordre d'aucune sorte.
    C'est à vous de décider de ce que vous faites.
    Lisez l'article que j'ai écrit à ce sujet :
    http://sqlpro.developpez.com/cours/sqlaz/erreurs/#L6

    En particulier le SELECT * peut vous renvoyer l'ordre des colonnes que le sgbd désire et ce à chaque exécution. C'est à vous de ne pas utiliser le SELECT * qui est fait uniquement pour la mise au point des requêtes et non pour la production. Il n'y a rien de dangereux, mais simplement votre méconnaissance de ce qu'est un SGBD relationnel basé sur des principes ensemblistes.

    QUESTIONS :
    si je vous donne mon sac de bille pouvez vous me dire quelle est la dernière bille insérée ?
    si je vous donne mon sac de bille, pour chaque bille sortie du sac et que je vous demande de décrire minutieusement chaque bille, avez vous une chance sur 1000 de me donner les caractéristique des billes dans le même ordre que le ferait votre cousin ?

    Bref, commencez par apprendre ce qu'est un SGBD relationnel et comment on utilise le langage SQL et vous y verrez plus clair. Mes bouquins 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/ * * * * *

  9. #9
    Membre régulier
    Inscrit en
    Décembre 2004
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 112
    Points : 94
    Points
    94
    Par défaut
    Merci pour vos remarques!

    en fait je voulais utliser une vue avec select * pour avoir une copie virtuelle de toutes les colonnes de ma table avec juste une partie du contenu de la table!
    la raison c'est que comme ca, j'eviterais les erreurs qui pourrait etre causé en cas de suppression de colonnes, mais aussi en cas d'ajout de nouvelles colonnes je pensais qu'elle seraient automatiquement ajouté à ma vue!

    mais d'apres les remarques que j'ai lu, il faut apres chaque changement dans la table aller changer la vue... c'est pas tres pratique, sauf s'il ya un moyen de le faire automatiquement.

    Perso, j'eviterai des à present d'utiliser des vues...

  10. #10
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 848
    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 848
    Points : 52 964
    Points
    52 964
    Billets dans le blog
    6
    Par défaut
    Le SELECT * ne doit JAMAIS être utilisé ! C'est un outil de mise au point, pas un outil de production...

    Perso, j'eviterai des à present d'utiliser des vues...
    Ca c'est la bétise... En principe on ne devrait accéder à un SGBDR jamais que par des vues. L'inverse conduit à des problèmes indémerdables à terme.

    Ceci est connu depuis les années 70 ou Codd à inventé les SGBD relationnel et notamment ajouté la notion de "schema externe" afin d'éviter les problématiques des anciennes bases de données non relationnelles liées aux fichiers.

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

  11. #11
    Membre régulier
    Inscrit en
    Décembre 2004
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 112
    Points : 94
    Points
    94
    Par défaut
    Merci SQLpro pour vos conseils!

    j'admets que le select * ne doit pas etre utilisé.
    Mais si on supprime (voir on renomme) une colonne de la table, il y aura un message d'erreur lors de l'ouverture de la vue... comment ferez vous pour eviter cela ?!


    Merci!

  12. #12
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonsoir,

    La différence entre une talbe et une vue est que la table est un objet "physique", c'est à dire qu'il demande de la mémoire. Ce n'est pas le cas de la vue qui est un objet purement logique : en effet vous définissez une vue en écrivant une requête SELECT. Une vue ne consomme pas de mémoire.

    Passons à "l'ordre" de vos colonnes
    Soit :
    - une table Tb_Client (IDClient,Nom,Prénom,Adresse),
    - une table Tb_ClientCompte (IDClient, IDCompte)
    - une table Tb_Compte (IDCompte, NomCompte).

    Je définis ma vue V_CaracteristiqueClient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE VIEW V_CaracteristiqueClient AS
    SELECT CLI.Nom,
    		CLI.Prenom,
    		CLI.Adresse,
    		CPT.NomCompte
    FROM dbo.Tb_Client CLI
    INNER JOIN dbo.Tb_ClientCompte CLICPT ON CLI.IDClient = CLICPT.IDClient
    INNER JOIN dbo.Tb_Compte CPT ON CPT.IDCompte = CLICPT.IDCompte;
    Donc "l'ordre" des colonnes si je fais un SELECT * FROM V_CaracteristiqueClient histoire de voir ce que donne un peu ma jointure, sera Nom, Prenom, Adresse, NomCompte

    Maintenant je modifie la table Tb_Client (IDClient,Nom,Prénom,Adresse) en Tb_Client (IDClient,Prénom,Nom,Adresse), mais la definition de ma vue V_CaracteristiqueClient n'a pas changé, donc les colonnes de cette vue seront sélectionnées de la même façon que précédemment

    Si je veux changer l'ordre d'affichage de ma vue, je dois écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ALTER VIEW V_CaracteristiqueClient AS
    SELECT CLI.Prenom,
    		CLI.Nom,		
    		CLI.Adresse,
    		CPT.NomCompte
    FROM dbo.Tb_Client CLI
    INNER JOIN dbo.Tb_ClientCompte CLICPT ON CLI.IDClient = CLICPT.IDClient
    INNER JOIN dbo.Tb_Compte CPT ON CPT.IDCompte = CLICPT.IDCompte;
    Donc nul besoin de changer la définition de la table, il suffit de changer la définition de la vue , c'est 100 fois plus facile !!!

    A+

  13. #13
    Membre régulier
    Inscrit en
    Décembre 2004
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 112
    Points : 94
    Points
    94
    Par défaut
    Bonjour et merci pour l'explication elsuket!

    je vais continuer dans ton exemple:
    si tu changes par exemple la tabe Tb_Compte (IDCompte, NomCompte) en Tb_Compte (IDCompte, AliasCompte), et tu fais un "SELECT * FROM V_CaracteristiqueClient"
    t'auras un message qui indique que NomCompte n'existe pas, tu devrais donc redifinir la vue V_CaracteristiqueClient...

    donc c'est là le probleme... si on change quelque chose dans nos table (ajouts, suppressions de colonnes), les vues doivent etre redefinies!
    moi qui pensais pouvoir regler le probleme avec un Select * dans les vues... C'est bien dommage que notre SGBDR ne puisse s'occuper de ca!

    Merci encore!

Discussions similaires

  1. Réponses: 9
    Dernier message: 20/03/2007, 19h56
  2. [Sql Server 2000] Création de vue complexe
    Par sofien dans le forum Langage SQL
    Réponses: 2
    Dernier message: 27/12/2006, 10h10
  3. Requête sur Vue SQL Server 2000 PLANTE aléatoirement
    Par StarMusic dans le forum Bases de données
    Réponses: 1
    Dernier message: 07/11/2006, 10h22
  4. Minus,intersect,union et vue avec sql server 2000
    Par donny dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 22/02/2006, 07h46
  5. [SQL Server 2000] ajouter une colonne identité dans une vue?
    Par CetTer dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 02/08/2005, 13h43

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