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 :

Fonction pour contrôle de format de date


Sujet :

Développement SQL Server

  1. #1
    Candidat au Club
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Points : 4
    Points
    4
    Par défaut Fonction pour contrôle de format de date
    Bonjour,

    Je suis sur la création d'une fonction nommée EstUneDate et prenant en entrée deux chaînes de caractère et vérifiant que chacune d'entre elles correspondent respectivement aux formats 'DD/MM/YYYY' et 'HH24:MI' (que les deux chaînes forment bien une date valide, sans se préoccuper des secondes). Ceci pour effectuer un contrôle de la qualité des données d'un fichier .csv que je charge initialement dans une table temporaire. Malheureusement je rencontre une incohérence dès le premier If Then Else. Je me demande s'il ne s'agit pas d'une erreur de syntaxe.

    J'ai créé une premier fonction LastDayOfMonth dont je me sers dans la seconde. Je sais qu'en terme de perf je ne dois pas être dans les best practices mais je n'ai qu'au maximum un fichier de 100 000 - 200 000 lignes à intégrer par semaine. Donc avant de m'occuper des perfs, j'aimerais bien déjà que ça fonctionne

    Voici les scripts de mes deux fonctions:

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    CREATE FUNCTION [dbo].[LastDayOfMonth](@InMonth integer,@InYear integer)
    RETURNS integer
    AS
    BEGIN
    	DECLARE @MyOutput Integer
    	IF @InMonth IN (1,3,5,7,8,10,12) BEGIN SET @MyOutput=31 END
    	IF @InMonth IN (4,6,9,11) BEGIN SET @MyOutput=30 END
    	IF @InMonth = 2 AND @InYear%4 = 0 BEGIN SET @MyOutput=29 END
    	IF @InMonth = 2 AND @InYear%4 <> 0 BEGIN SET @MyOutput=28 END
    	RETURN @MyOutput
    END
    GO
    
    CREATE FUNCTION [dbo].[EstUneDate](@InDate varchar,@InHeure varchar)
    RETURNS integer
    AS
    BEGIN
    	DECLARE @MyOutput Integer
    	DECLARE @DD Varchar(2)
    	DECLARE @MM Varchar(2)
    	DECLARE @YYYY Varchar(4)
    	DECLARE @HH Varchar(2)
    	DECLARE @MI Varchar(2)
    	SET @MyOutput = 0
    	-- Test de la longueur des chaînes en entrée
    	IF LEN(@InDate) != 10 BEGIN 
    	SET @MyOutput = 1 
    	END
    	ELSE BEGIN
    	IF LEN(@InHeure) != 5 BEGIN 
    	SET @MyOutput = 2 
    	END
    	ELSE BEGIN
    	-- Test des séparateurs
    	IF SUBSTRING(@InDate,3,1) <> '/' BEGIN 
    	SET @MyOutput = 3 
    	END
    	ELSE BEGIN
    	IF SUBSTRING(@InDate,6,1) <> '/' BEGIN 
    	SET @MyOutput = 4 
    	END
    	ELSE BEGIN
    	IF SUBSTRING(@InHeure,3,1) <> ':' BEGIN 
    	SET @MyOutput = 5 
    	END
    	ELSE BEGIN
    	SET @DD = SUBSTRING(@InDate,1,2)
    	SET @MM = SUBSTRING(@InDate,4,2)
    	SET @YYYY = SUBSTRING(@InDate,7,4)
    	SET @HH = SUBSTRING(@InHeure,1,2)
    	SET @MI = SUBSTRING(@InHeure,4,2)
    	-- Test des numériques
    	IF NOT(ascii(@DD) between 48 and 57) BEGIN 
    	SET @MyOutput = 6 
    	END
    	ELSE BEGIN
        IF NOT(ascii(@MM) between 48 and 57) BEGIN 
        SET @MyOutput = 7 
        END
    	ELSE BEGIN
        IF NOT(ascii(@YYYY) between 48 and 57) BEGIN 
        SET @MyOutput = 8 
        END
    	ELSE BEGIN
    	IF NOT(ascii(@HH) between 48 and 57) BEGIN 
    	SET @MyOutput = 9 
    	END
    	ELSE BEGIN
    	IF NOT(ascii(@MI) between 48 and 57) BEGIN 
    	SET @MyOutput = 10 
    	END
    	ELSE BEGIN
    	-- Test des valeurs
    	IF NOT(CAST(@DD as integer) between 1 and 31) BEGIN 
    	SET @MyOutput = 11 
    	END
    	ELSE BEGIN
    	IF NOT(CAST(@MM as integer) between 1 and 12) BEGIN 
    	SET @MyOutput = 12 
    	END
    	ELSE BEGIN
    	IF NOT(CAST(@YYYY as integer) between 1900 and 2099) BEGIN 
    	SET @MyOutput = 13 
    	END
    	ELSE BEGIN
    	IF NOT(CAST(@HH as integer) between 0 and 23) BEGIN 
    	SET @MyOutput = 14 
    	END
    	ELSE BEGIN
    	IF NOT(CAST(@MI as integer) between 0 and 59) BEGIN 
    	SET @MyOutput = 15 
    	END
    	ELSE BEGIN
        -- Dernier Jour du Mois
    	IF CAST(@DD as integer) > dbo.LastDayOfMonth(CAST(@MM as integer),CAST(@YYYY as integer)) BEGIN 
    	SET @MyOutput = 16 
    	END
    	ELSE BEGIN 
    	SET @MyOutput = 17 
    	END
    	END 
    	END 
    	END 
    	END 
    	END
    	END 
    	END 
    	END 
    	END 
    	END
    	END 
    	END 
    	END 
    	END 
    	END
    	RETURN @MyOutput
    END
    GO
    Notez que dans EstUneDate, les affectations à @MyOutput sont incrémentées uniquement dans un soucis de debugging. Au final, je souhaite une fonction qui renvoie 1 si les deux chaînes en entrée sont au bon format, et 0 sinon.

    Merci de votre coup de main!

  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
    Pourquoi réinventer la roue ?
    ISDATE()

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

  3. #3
    Candidat au Club
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    Je ne connaissais pas. Effectivement ça peut m'aider. Mais la fonction ISDATE me semble trop permissive toute seule. Je veux être sûr d'avoir un format DD/MM/YYYY et pas YYYY/MM/DD.

    Je vais essayer de combiner cette fonction avec un test de parsing sur les champs texte en entrée.

    Merci.

  4. #4
    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
    Et récrire votre fonction comme ceci :

    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
    CREATE FUNCTION [dbo].[LastDayOfMonth](@InMonth integer,@InYear integer)
    RETURNS integer
    AS
    BEGIN
    RETURN
       CASE
          WHEN @InMonth IN (1,3,5,7,8,10,12) THEN 31
          WHEN @InMonth IN (4,6,9,11)        THEN 30
          WHEN @InMonth = 2 
           AND @InYear % 4 <> 0 THEN 28
          WHEN @InMonth = 2
           AND @InYear % 4 = 0
           AND @InYear % 100 = 0
           AND @InYear % 400 <> 0 THEN 28
          ELSE 29
       END
    END
    GO

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

  5. #5
    Membre actif
    Inscrit en
    Janvier 2012
    Messages
    145
    Détails du profil
    Informations forums :
    Inscription : Janvier 2012
    Messages : 145
    Points : 226
    Points
    226
    Par défaut
    Peux tu essayer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT day(CONVERT(VARCHAR(10),DATEADD(dd,-(DAY(DATEADD(mm,1,'03/02/2012'))),DATEADD(mm,1,'03/02/2012')),103))
    qui renvoie bien le 29 pour notre année bissextile.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT day(CONVERT(VARCHAR(10),DATEADD(dd,-(DAY(DATEADD(mm,1,'03/15/2012'))),DATEADD(mm,1,'03/15/2012')),103))
    renvoie par contre une erreur car on n'est pas dans le bon format. Je pense que cela te permet de vérifier à la fois que c'est une date dans ton format et d'avoir le dernier jour. Sur SQL Server 2012 il y a parait il une fonction EOMONTH()...

  6. #6
    Candidat au Club
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    Merci de votre coup de main. J'y suis arrivé sans soucis grâce à ISDATE()

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

Discussions similaires

  1. [XL-2010] Fonction pour formater une Textbox (Date)
    Par JapethTheGoat dans le forum Macros et VBA Excel
    Réponses: 21
    Dernier message: 19/03/2015, 15h09
  2. Fonction pour la comparaison entre deux dates
    Par malouchka dans le forum R
    Réponses: 3
    Dernier message: 01/09/2014, 15h36
  3. Problème pour controler un format de date
    Par mohamed_75 dans le forum IHM
    Réponses: 3
    Dernier message: 18/10/2010, 14h19
  4. Version Francaise de MSDE pour le format de date
    Par Drahu dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 25/11/2004, 18h06

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