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

Développement SQL Server Discussion :

Probleme de comparaison de datetime


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut Probleme de comparaison de datetime
    Bonjour tout le monde
    je fais une requête sur ma table qui contient un champs de datetime (DateDebut) pour récupérer tout les enregistrements avec DateDebut superieur à une date que j'indique, mais elle ne marche pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      select * from Conges where DateDebut >= 30/07/2010
    d'après mes recherches sur internet ma requête est correcte et je dois avoir un résultat, mais ce n'est pas le cas.
    je signale que les date sont stockées dans ma table Conges sous le format yyyy-mm-dd hh:mm:ss:mm.mmmm

    peut cela être la cause de mon problème ?

  2. #2
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 710
    Points : 4 794
    Points
    4 794
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM Conges WHERE DateDebut >= CONVERT(DateTime,'2010/07/30',120)
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par casawi Voir le message
    je signale que les date sont stockées dans ma table Conges sous le format yyyy-mm-dd hh:mm:ss:mm.mmmm
    On ne répétera vraisemblablement jamais assez, les dates n'ont pas de format !!!
    Le format s'est juste pour l'esthétique de l'affichage.

  4. #4
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut
    Merci Népomucène pour la réponse et aussi Jerome_Mtl pour la remarque
    j'ai pas encore résolu mon problème.
    je mets mon code tout entier, comme ça vous serez près de mon problème:
    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
     
    ALTER PROCEDURE [dbo].[GetListeConges] 	
    ( 	
    	@Id numeric(18,0),
    	@IdType numeric(18,0),
     	@DateDebut nvarchar(20),
    	@DateFin nvarchar(20)
    ) 	
    AS
    DECLARE @REQ varchar(800)
    BEGIN 	
     
    	SET @REQ = 'SELECT Conges.IdConge FROM Conges 
    		        WHERE Conges.IdUser = '+ cast(@Id as varchar(10));
    	if @IdType is not null
    		SET @REQ = @REQ + ' AND Conges.IdTypeConge = ' + cast(@IdType as varchar(10));
    	if @DateDebut is not null and @DateDebut <> ''
    		SET @REQ = @REQ + ' AND Conges.DateDebutConge >= '+convert(datetime,@DateDebut, 103);
    	if @DateFin is not null and @DateFin <> ''
    		SET @REQ = @REQ + ' AND Conges.DateFinConge <= ' + convert(datetime,@DateFin, 103);
    	SET @REQ = @REQ + ' ORDER BY Conges.DateDebutConge';
    	PRINT 'REQ : '+@REQ;
    	EXEC(@REQ);
    END
    Merci encore

  5. #5
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Je ne comprends pas pourquoi tu balades des datetime sous forme de chaines.

    Les paramètres d'entrées de la proc stoc : elle est appelée par quoi cette proc stoc que tu ais des paramètres de date en chaine ?

    Par ailleurs utiliser le Convert avec le paramètre 103 ne correspond pas au format de chaine date ton tu parles dans ton premier poste.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  6. #6
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut
    Merci Bluedeep pour ta réponse
    j'appelle ma procédure d'un code c#. J'ai choisi de transmettre mes dates en chaine par ce que j'ai trouvé des problème lorsque mon datetime est null.
    pour le format c'est vrai il ne correspond pas à 103, mais le format que je récupère et que je le passe à mon code c# est jj/mm/yyyy (le 103).

  7. #7
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par casawi Voir le message
    Merci Bluedeep pour ta réponse
    j'appelle ma procédure d'un code c#. J'ai choisi de transmettre mes dates en chaine par ce que j'ai trouvé des problème lorsque mon datetime est null.
    Quel problème ? tu utilises des DateTime nullable (syntaxe C# : "DateTime?") et c'est tout. Il n'y aucune justification pour introduire ce genre de monstruosité dans le code (sans même parler de l'effet d'un changement de Localisation sur la machine exécutant le code).

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  8. #8
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 710
    Points : 4 794
    Points
    4 794
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ALTER PROCEDURE [dbo].[GetListeConges] 	
    ( 	
    	@Id numeric(18,0),
    	@IdType numeric(18,0),
     	@DateDebut nvarchar(20) NULL,
    	@DateFin nvarchar(20) NULL
    ) 	
    AS ...
    Comme ça, tu n'es pas obligé de fournir @DateDebut et @DateFin à la procédure si l'application C# prévoit que ces paramètres sont optionnels.

    qu'est-ce qui ne marche toujours pas dans la requête ?



    .
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  9. #9
    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,

    d'après mes recherches sur internet ma requête est correcte et je dois avoir un résultat, mais ce n'est pas le cas.
    je signale que les date sont stockées dans ma table Conges sous le format yyyy-mm-dd hh:mm:ss:mm.mmmm
    Comme écrit précédemment par Jérôme_Mtl, les dates n'ont pas de format.
    Un SGBDR n'est pas conçu pour présenter des données, mais pour les stocker, éventuellement les traiter, et les restituer.
    La présentation des données se fait côté applicatif

    En effet, dans SQL Server, les valeurs stockées dans une colonne de type DATETIME le sont en fait sous la forme de deux entiers de 4 octets :

    - un pour la date, qui est le nombre de jours écoulés depuis une certaine date (sous SQL Server 2008 c'est le 1er Janvier 1753)
    - un pour le nombre de millisecondes écoulées depuis minuit.

    Donc ce que vous voyez sous SQL Server Management Studio, qui est une application, mais pas la base de données, n'est qu'une représentation de ce qui est stocké dans une telle colonne.

    Il suffit d'ailleurs de regarder la documentation de la fonction CONVERT() pour s'apercevoir qu'on peut modifier à sa guise le format d'une date retourné à une application cliente : une vingtaine de formats sont possibles !

    Je remarque également que vous utilisez le type NUMERIC avec zéro décimales, ce qui revient donc à un entier.
    Avec la mantisse que vous autorisez, et en supposant que cela correspond exactement au type de la colonne IdUser de la table Conges, vous utilisez donc 9 octets.
    Or si vous aviez utilisé le type INT, qui vous permet de stocker plus de 4 milliards de valeurs différentes (dans votre cas, ce serait 2/3 de la population mondiale ), vous n'utiliseriez que 4 octets.
    Donc votre prédicat de jointure va requérir plus de ressources CPU

    Je suppose que cet IdUser fait référence à une table d'utilisateurs dont celle-ci est clé primaire.
    Or pour toute clé primaire, un index cluster est crée automatiquement.
    La clé de l'index cluster, c'est à dire ici la colonne IdUser, est référencée par tous les index non-cluster de la table.
    Donc comme votre clé fait 9 octets au lieu de 4, et que la taille d'une page de données est "limitée" à 8000 octets de données utilisateur, vous allez stocker moins de valeur de clé, donc vos requêtes devront lire plus de pages, requérir plus de mémoire puisqu'il faut stocker en RAM plus de pages, et plus de CPU pour effectuer la jointure.

    Tout ça parce que vous n'utilisez pas le bon type de données, avouez que c'est dommage

    Dans votre cas, vous voulez créer une requête de façon dynamique.
    Mais cela ne vous empêche pas de passer des paramètre de type datetime en entrée de votre procédure stockée.
    Il vous faut ensuite utiliser le format ISO pour les dates (YYYYMMDD) qui fonctionne quel que soit le langage de votre plateforme, ce que vous permet la fonction CONVERT() avec les formats 112 et 108 :

    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
    32
    ALTER PROCEDURE dbo.GetListeConges
    	@_Id numeric(18,0),
    	@_IdType numeric(18,0),
     	@_DateDebut datetime = NULL,
    	@_DateFin datetime = NULL
    AS
    BEGIN
    	IF @_DateDebut IS NULL AND @_DateFin IS NULL
    	BEGIN
    		RAISERROR('L''une des deux dates de début et de fin de période doivent être fournis', 16, 1)
    		RETURN
    	END
     
    	DECLARE @DateDebutChaine nchar(17)
    		, @DateFinChaine nchar(17)
     
    	SELECT	@DateDebutChaine = CONVERT(nchar(8), @_DateDebut, 112) + ' ' + CONVERT(nchar(8), @_DateDebut, 108)
    		, @DateFinChaine = CONVERT(nchar(8), @_DateFin, 112) + ' ' + CONVERT(nchar(8), @_DateFin, 108)
     
    	DECLARE @sql nvarchar(1024)
    	SET @sql = 'SELECT IdConge FROM dbo.Conges WHERE IdUser = ' + CAST(@_Id AS varchar(18))
     
    	SELECT	@sql = CASE WHEN @_IdType IS NOT NULL THEN ' AND IdTypeConge = ' + CAST(@_IdType AS varchar(18)) ELSE '' END
    			+ CASE WHEN @_DateDebut IS NOT NULL THEN ' AND DateDebutConge >= ' + @DateDebutChaine ELSE '' END
    			+ CASE WHEN @_DateFin IS NOT NULL THEN ' AND DateFinConge >= ' + @DateFinChaine ELSE '' END
     
    	SET	@sql = @sql + ' ORDER BY DateDebutConge'
     
    	-- PRINT @sql
     
    	EXEC sp_executeSQL @sql
    END
    N'oubliez jamais de qualifier le nom des objets (tables, procédures stockées et fonctions) auxquels vous accédez par le nom du schéma auquel ils appartiennent (dans votre cas je pense que c'est dbo), cela évite au moteur de base de données de le rechercher

    Utilisez la procédure stockée sp_executeSQL pour exécuter du code SQL construit dynamiquement : cela vous permet de conserver les plans de requête, donc d'éviter les compilations à chaque exécution

    @++

  10. #10
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 710
    Points : 4 794
    Points
    4 794
    Par défaut
    Ah oui tiens, hier soir j'ai oublié le signe "=" dans les paramètres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     	@_DateDebut datetime = NULL,
    	@_DateFin datetime = NULL
    Sinon je suis bien d'accord avec tous les rappels de elsuket concernant les types NUMERIC / INT.
    Mais le nom de la procédure "GetListeConges" indique une base de gestion du personnel.
    Il est possible que casawi ne soit pas responsable de la structuration de la base si les données viennent de la base d'un logiciel de pointeuse par exemple.

    Je suis en train de bosser avec une base de ce type dont je préfère taire le nom.
    C'est une vraie galère : toutes les dates sont stockées en varchar dans des champs séparés des heures (également en varchar).
    Résultat : pour faire des stats tu patouilles les requêtes avec CONVERT

    Bon la vraie question maintenant : casawi est-ce que le problème est résolu ?
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  11. #11
    Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    191
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 191
    Points : 53
    Points
    53
    Par défaut
    Bonjour
    Merci beaucoup les amis pour vos conseils, et éclaircissements.
    j'ai essayé ta solution elsuket, et j'ai l'erreur suivante :
    Msg*156, Niveau*15, État*1, Ligne*1
    Incorrect syntax near the keyword 'AND'.
    je pense que le problème vient de l'évaluation de mes dates.
    j'ai ajouté un print pour avoir une idée sur le problème, et ça donne
    SELECT IdConge FROM dbo.Conges WHERE IdUser = 48 AND IdTypeConge = 12 AND DateDebutConge >= 20101208 00:00:00 ORDER BY DateDebutConge

  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
    Désolé : en effet il te faut remplacer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    			+ CASE WHEN @_DateDebut IS NOT NULL THEN ' AND DateDebutConge >= ' + @DateDebutChaine ELSE '' END
    			+ CASE WHEN @_DateFin IS NOT NULL THEN ' AND DateFinConge >= ' + @DateFinChaine ELSE '' END
    Par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    			+ CASE WHEN @_DateDebut IS NOT NULL THEN ' AND DateDebutConge >= ''' + @DateDebutChaine + ''' ELSE '' END
    			+ CASE WHEN @_DateFin IS NOT NULL THEN ' AND DateFinConge >= ''' + @DateFinChaine + ''' ELSE '' END
    Pour permettre à SQL Server de transtyper automatiquement de chaîne en date

    @++

Discussions similaires

  1. probleme de comparaison de date
    Par witjet dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 04/07/2006, 11h39
  2. Problème de comparaison de fichiers
    Par peppena dans le forum Shell et commandes GNU
    Réponses: 10
    Dernier message: 30/05/2006, 19h41
  3. [VBS]probleme ds comparaison de nombres
    Par zorba49 dans le forum VBScript
    Réponses: 9
    Dernier message: 24/05/2006, 16h43
  4. [VBA-E] Comparaison date / datetime
    Par dahu29 dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 15/03/2006, 13h12
  5. [Dates] Probleme de comparaison de date
    Par mathieu77186 dans le forum Langage
    Réponses: 4
    Dernier message: 22/12/2005, 17h21

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