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 :

Problème de test sur un champ


Sujet :

MS SQL Server

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    138
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Maroc

    Informations forums :
    Inscription : Mai 2007
    Messages : 138
    Points : 72
    Points
    72
    Par défaut Problème de test sur un champ
    Bonjour tout le monde.
    Mon problème est que, dans mon application, j'utilise des requêtes SQL et des procédures stockées, et dans une de mes requêtes, ci-jointe, je dois tester sur les valeurs de 4 champs: {Date1Du; Au}; {Date2Du; Au}, et je ne peux avoir les 4 champs remplis à la fois, c'est soit {Date1Du; Au} ou bien {Date2Du; Au}, sinon, les deux vides.
    Je dois avoir une seule requête qui à la fois teste si des champs sont remplis, et suivant le résultat, on affichera le résultat de la recherche.
    Ci-dessous ma requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT Champ1, Date1,Champ2,Champ3,Champ4,Champ5,Champ6,Champ7, Date2
    FROM   Table1,Table2,Table3,Table4  
    WHERE
    	Table1.idd = Table4.idd  
    	AND Table1.num1 = Table2.num1  
    	AND Table1.num2 = Table3.num2  
    	AND Table1.etat = (SELECT etat FROM Table4 WHERE libelle = 'Destruction') 
    	AND (Table1.num1 in (SELECT num1 FROM Table3 WHERE num2 in (SELECT num2 FROM Table5 WHERE Nuser ='12')or num2='5685')or Table1.num1='1379') 
    	AND isnull(Champ6,0) LIKE ''+ '' + '%' 
    	AND isnull(Champ5,0) like ''+ '' +'%'  
    	AND isnull(Table1.Date1,'01/01/1900') BETWEEN   ISNULL('','01/01/2008')  AND   ISNULL('','31/12/2009')  
    	AND ISNULL(Table1.Date2,'01/01/1900')  BETWEEN   ISNULL('01/01/2008','01/01/2008')  AND   ISNULL('31/12/2010','31/12/2009')
    	AND isnull(Table1.Champ2,0) like ''+ '' +'%'
    ORDER BY 
    	Date1
    Le problème se pose au niveau du test sur les valeurs Date1 et Date2. je n'ai pas le résultat attendu.

    Quelqu'un aurait-il une explication ?

    Merci d'avance.
    Imad_Ing
    Softwear Engineer

    Petit à petit, Rôme est batie

  2. #2
    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
    Bonjour,

    Vous devez savoir que NULL n'est pas une valeur : c'est un marqueur qui signifie l'absence de valeur.
    Dès lors NULL n'est pas même égal à lui-même.
    Ainsi si nous exécutons :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF NULL = NULL
    	PRINT 'OK'
    ELSE PRINT 'KO'
    Nous obtenons KO. Il en va de même pour toute autre comparaison, donc pour BETWEEN.

    Ensuite la fonction ISNULL retourne la valeur de son second paramètre si le premier est NULL.
    Donc si vous écrivez :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ISNULL('','01/01/2008')
    Vous obtiendrez forcément '01/01/2008'.

    Il en va de même pour :

    - ISNULL('01/01/2008','01/01/2008') qui vous retournera toujours '01/01/2008'
    - ISNULL('31/12/2010','31/12/2009') qui vous retournera toujours '31/12/2010'

    En effet '' (chaîne vide) n'est pas NULL.

    Ensuite vous utilisez les jointures dans le WHERE qui sont d'un autre temps.
    Prenez l'habitude d'utiliser le prédicat JOIN, qui vous permet de séparer vos jointures de vos filtres de requête, qui eux sont après le WHERE.

    Vos LIKE sont bizarrement spécifiés. '' signifie chaîne vide, donc cela n'a pas sa place dans un LIKE.
    Cela fonctionne quand même, mais vous utilisez le joker %, qui signifie tout caractère.
    Donc je ne sais pas ce que vous souhaitez filtrer, mais dans votre requête ils sont inutiles.

    Vous n'avez pas non plus qualifié le nom des tables par le nom du schéma auquel elles appartiennent, ce uqi oblige le moteur de base de données à interroger les tables de métadonnées pour savoir dans quel schéma elles sont, même si c'est celui par défaut : dbo.

    Vous n'avez pas non plus qualifié le nom des colonnes par la table à laquelle elle appartient, ce qui obligera vous ou le développeur qui passera après vous à regarder la structure des 5 tables de votre requête pour savoir d'où provient telle ou telle colonne le jour ou vous la ré-éditerez.

    Tout cela vous permet donc de corriger votre requête vers :

    Code : 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
    SELECT		Champ1
    		, date1
    		, Champ2
    		, Champ3
    		, Champ4
    		, Champ5
    		, Champ6
    		, Champ7
    		, date2
    FROM		dbo.Table1 AS T1
    INNER JOIN	dbo.Table2 AS T2
    			ON T1.num1 = T2.num1
    			OR T1.num1 = '1379'
    INNER JOIN	dbo.Table3 AS T3
    			ON T1.num2 = T3.num2
    			AND T1.num1 = T3.num1
    			OR T1.num2 = '5685'
    INNER JOIN	dbo.Table4 AS T4
    			ON T1.idd = T4.idd
    			AND T1.etat = T4.Etat
    INNER JOIN	dbo.Table5 AS T5
    			ON T3.num2 = T5.num2
    WHERE		T4.libelle = 'Destruction'
    AND		T5.Nuser = '12'
    --AND		ISNULL(Champ6,0) LIKE ''+ '' + '%' 
    --AND		ISNULL(Champ5,0) LIKE ''+ '' +'%'  
    AND 		(
    			date1 BETWEEN CAST('19000101' AS DATETIME) AND CAST('20120101' AS DATETIME)
    			OR date2 BETWEEN CAST('19000101' AS DATETIME) AND CAST('20120101' AS DATETIME
    		)
    ORDER BY	date1
    Enfin sachez que l'utilisation de OR n'est pas SARGable.

    Vous pouvez donc créer une colonne calculée pour outrepasser ce comportement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE maTable
    ADD maColonne AS (ISNULL(date1, date2))
    Ce qui vous permet de changer la dernière clause AND par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND 		maColonne BETWEEN CAST('19000101' AS DATETIME) AND CAST('20120101' AS DATETIME)
    Ce qui rend SARGable votre filtre.

    Pour ajouter de la vitesse, vous pouvez penser à indexer la colonne calculée, mais comme je n'ai pas les tables desquelles proviennent les autres colonnes, je ne peux pas vous aider là-dessus.

    @++

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    138
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Maroc

    Informations forums :
    Inscription : Mai 2007
    Messages : 138
    Points : 72
    Points
    72
    Par défaut
    Merci beaucoup elsuket pour ta réponse.
    Je l'applique tout de suite et je te fait un retour
    Imad_Ing
    Softwear Engineer

    Petit à petit, Rôme est batie

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    138
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Maroc

    Informations forums :
    Inscription : Mai 2007
    Messages : 138
    Points : 72
    Points
    72
    Par défaut
    Ca a résolu mon problème.

    Merci encore elsuket
    Imad_Ing
    Softwear Engineer

    Petit à petit, Rôme est batie

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

Discussions similaires

  1. [AC-2003] Problème de test sur plusieurs champs dans une table
    Par Cavart dans le forum Access
    Réponses: 1
    Dernier message: 23/11/2011, 14h51
  2. [Dates] Test sur un champ de formulaire
    Par rdams dans le forum Langage
    Réponses: 4
    Dernier message: 15/09/2005, 16h03
  3. Réponses: 4
    Dernier message: 16/06/2005, 15h37
  4. Test sur un champs vide
    Par PrinceMaster77 dans le forum ASP
    Réponses: 2
    Dernier message: 27/04/2004, 12h54
  5. [CR] Problème de sélection sur un champ date
    Par noluc dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 21/11/2003, 16h56

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