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 :

[2008R2] Deux requêtes même résultat


Sujet :

MS SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Billets dans le blog
    4
    Par défaut [2008R2] Deux requêtes même résultat
    Bonjour,

    je me retrouve avec un soucis au sujet d'un retour de requête qui me parait étrange.

    Je vous donne les codes :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT *
      FROM dbo.tblUser
     WHERE UserID = '';
     
    SELECT *
      FROM dbo.tblUser
     WHERE UserID = 0;

    Le contexte : Sur une table avec un UserID Int Non NULL Indentity(1, 1)

    Le soucis : Comment ces deux requêtes peuvent me retourner le même résultat, à savoir la ligne dont le UserID = 0 ? ce qui me pose soucis dans beaucoup de requêtes puisque j'ai parfois des jointures sur des fichiers fournis ou les données du UserID sont '' ce qui fait qu'il me compte la ligne UserID 0 comme étant égale à celles dont le UserID = ''

    Est-ce un comportement normal, ou est-ce un soucis de ma Base et donc qu'il faut que je prennent en compte ce problème?

    Cordialement,
    Lyche
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  2. #2
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 254
    Par défaut
    Oui, il y a un soucis.

    '' ne signifie pas et n'a jamais signifié et ne signifiera jamais Null.

    Ta colonne est de type Int, le paramètre que tu passe n'est pas de type Int. Le moteur SQL met donc en place une variable interne afin de pouvoir effectuer la conversion, variable de type Int avec comme valeur par défaut 0.
    '' n'étant pas une valeur numérique, la conversion ne peut être faite et donc la variable interne est utilisée avec sa valeur par défaut qui est 0
    Donc '' = 0

    Refait ta requette avec UserID IS NULL et tu verra la différence

  3. #3
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Attention, avec Oracle, '' is null

    Et si je ne m'abuse, on peut paramétrer SQL Server pour avoir le même comportement !

    Vérifiez donc les paramètres de votre base de données.

  4. #4
    Membre expérimenté
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Billets dans le blog
    4
    Par défaut
    je cherchais pas les null, je sais très bien qu'un ne cherche pas un null en faisant un = null...

    Je me demandais pourquoi = '' me donnait le même résultat que = 0.

    Répondre aux gens c'est cool, je te remercie de la réponse, mais essaye de pas les prendre pour des incompétents non plus...
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  5. #5
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Je confirme le comportement absolument étrange !

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    create table test
    (
    	id int not null identity(1,1) primary key,
    	nom varchar(30) not null
    );
     
    set identity_insert test on;
    insert into test (id, nom) values (0, 'toto');
    insert into test (id, nom) values (1, 'titi');
    insert into test (id, nom) values (2, 'tata');
    set identity_insert test off;
     
    (1 row(s) affected)
     
    (1 row(s) affected)
     
    (1 row(s) affected)
     
    select *
    from test where id = 0;
     
    id          nom
    ----------- ------------------------------
    0           toto
     
    (1 row(s) affected)
     
    select *
    from test where id is null;
     
    id          nom
    ----------- ------------------------------
     
    (0 row(s) affected)
     
    select *
    from test where id = '';
     
    id          nom
    ----------- ------------------------------
    0           toto
     
    (1 row(s) affected)
     
    select * from test where 0 = '';
     
    id          nom
    ----------- ------------------------------
    0           toto
    1           titi
    2           tata
     
    (3 row(s) affected)

    D'après SQL Server, 0 = '' (???)

    Moi je vote, et je dis que ça pue le bug quand même...

    Parce que si on suit les règles de conversion implicite :

    '' converti en int ça devrait provoquer une excption "not a number" non ?
    Et dans l'autre sans, 0 devrait être transformé en '0' qui n'est en aucun cas égal à '' !

    Après vérifications, c'est bien '' qui est converti en 0 ! Attention, ' ' aussi est converti en 0 !

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    select CAST('' as int)
     
    -----------
    0
     
    (1 row(s) affected)
     
    select CAST(0 as varchar)
     
    ------------------------------
    0
     
    (1 row(s) affected)
     
    select CAST(' ' as int)
     
    -----------
    0
     
    (1 row(s) affected)
     
     
    select CAST('      ' as int)
     
    -----------
    0
     
    (1 row(s) affected)

    SQL Server 2008R2


    En tout cas, un exemple de plus qui prouve l'importance d'utiliser des requêtes paramétrée plutôt que des valeurs littérales quand on programme : un langage de haut niveau (C++, C#, Java, etc.) interdira la conversion implicite de '' en 0 et devrait résoudre le problème.

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Vous comparez un entier avec une chaîne de caractères => conversion implicite non maîtrisée => le mal.

  7. #7
    Membre expérimenté
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Moi je vote, et je dis que ça pue le bug quand même...
    un
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from maTable where 0 = '';

    retourne toutes les lignes de la table. Ce qui dans le sens d'interprétation de sevyc64 est tout à fait logique. Si le '' se convertis implicitement en 0 (et cette requête tend à me conforter dans vers cette voie. Alors la lecture de la requête sera 0 = 0. Donc Toujours vrai.

    En tout cas, un exemple de plus qui prouve l'importance d'utiliser des requêtes paramétrée plutôt que des valeurs littérales quand on programme : un langage de haut niveau (C++, C#, Java, etc.) interdira la conversion implicite de '' en 0 et devrait résoudre le problème.
    C'est vrai, sauf que je suis en gestion de BDD donc je ne passe pas par d'autres langages que le T-SQL, et que parfois les fichiers reçus des clients sont très très loin d'être bons. Il est vrai en revanche que j'aurais du convertir les '' de la table d'import en null, afin d'éviter ce soucis. Je ne pensais juste pas (je crois que j'avais eu le cas dans le passé mais que ça ne m'a pas marqué à ce moment là), que mon '' serait traité ainsi par le SGBD.

    Merci pour vos réponses et vos analyses.

    Cordialement,
    Lyche
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

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

Discussions similaires

  1. Importer le résultat de deux requête dans un Excel
    Par alexandrebergercyr dans le forum VBA Access
    Réponses: 3
    Dernier message: 08/05/2007, 18h21
  2. [SQL] Deux requêtes SQL sur le même formulaire
    Par amazircool dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 18/02/2007, 02h23
  3. MySQL me retourne deux fois le même résultat
    Par Romalafrite dans le forum Requêtes
    Réponses: 4
    Dernier message: 03/09/2006, 23h11
  4. [SQL2K]Une même requête des résultats différents
    Par jeeerome dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 11/07/2006, 14h20
  5. Afficher le ratio du résultat de deux requêtes
    Par decour dans le forum Access
    Réponses: 25
    Dernier message: 07/11/2005, 19h54

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