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 :

Problème Count dans un cursor


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 2
    Par défaut Problème Count dans un cursor
    Bonjour à Tous,

    Suite à un soucis sur une base de données j'ai mis en place un cursor
    qui m'insere dans une table tmp des numéros que je doit decoder pour retrouver des valeurs decoder par rapport une startdeate et endDate qu'ensuite je dois comparer avec une autre table mais le soucis que je rencontre et comme je fais un select count avec des états différents je m'apercois qui y a des doublons et que la sum du count du select 2 et 4 ne correspond pas au count du select 1 bien entendu que le numeros sont uniques j ai verifier si il y avait des doublons voici la partie du code en question si quelqu'un aurais une idée.

    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
    ------------------------------------------------------------------------------------------------------------
    DECLARE @valeur_a_decoder VARCHAR(100)
    DECLARE @critere1 VARCHAR(100)
    DECLARE @critere2 INT
    DECLARE @critere3 INT
    DECLARE @total_numeros_etat1_table2 INT
    DECLARE @total_numeros_etat1_table INT
    DECLARE @total_numeros_etat1_table_tmp INT
    DECLARE @total_numeros_etat2_table INT
    DECLARE @total_numeros_etat2_table_tmp INT
    DECLARE @total_numeros1_etat1_table INT
    DECLARE @total_numeros1_etat1_table_tmp INT
    DECLARE @total_numeros1_etat2_table INT
    DECLARE @total_numeros1_etat2_table_tmp INT
    DECLARE @Start_Period_Date	VARCHAR(300)
    DECLARE @End_Period_Date	VARCHAR(300)
     
     
    SET @Start_Period_Date = '20090101000000'
    SET @End_Period_Date   = '20090803235959'
     
    SELECT champs_a_decoder INTO #champs_a_decoder FROM table WHERE champs1 = 'status' and operation_date >= @Start_Period_Date and operation_date <= @End_Period_Date and error_text = 'status' 
    /*------------------------------------ SET TEMPORARY VARIABLES ------------------------------------------------------------------------------------------------*/
    SET @total_numeros_etat1_table_tmp = 0
    SET @total_numeros_etat2_table_tmp = 0
    SET @total_numeros1_etat1_table_tmp = 0
    SET @total_numeros1_etat2_table_tmp = 0
     
    DECLARE champs_a_decoder_cursor SCROLL CURSOR 
    FOR SELECT *  from #champs_a_decoder 
    OPEN champs_a_decoder_cursor
    FETCH NEXT FROM champs_a_decoder_cursor INTO @valeur_a_decoder
    WHILE @@fetch_status = 0
    BEGIN
     
    SET @critere1 = substring(@valeur_a_decoder,7,1)
    SET @critere2 = substring(@valeur_a_decoder,8,3)
    SET @critere3 = substring(@valeur_a_decoder,11,5)
    IF @critere1 = 1
    	BEGIN
    		SET @critere1 = 'XXXXX'
    END
    ELSE
    	BEGIN
    		SET @critere1 = 'YYYYY'
    END
     
    /* ---------------------------------------------------------SELECT 1 ---------------------------------------------------------------------------*/
    SELECT @total_numeros_etat1_table2 = COUNT(*) FROM table2 WHERE champ1 = @critere1 and champ2 = @critere2 and champ3 = @critere3 and state = 'etat1'
    IF @total_numeros_etat1_table2 = 1
    BEGIN
     
    		SET @total_numeros_etat1_table2_tmp = @total_numeros_etat1_table2_tmp + 1
    END
    /* ---------------------------------------------------------SELECT 2 ---------------------------------------------------------------------------*/
    SELECT @total_numeros_etat1_table = COUNT(*) FROM table2 WHERE champ1 = 'YYYYY' and champ2 = @critere2 and champ3 = @critere3 and state = 'etat1'
    IF @total_numeros_etat1_table_tmp = 1
    BEGIN
     
    		SET @total_numeros_etat1_table_tmp = @total_numeros_etat1_table_tmp + 1
    END
    /* ---------------------------------------------------------SELECT 3 ---------------------------------------------------------------------------*/
    SELECT @total_numeros_etat2_table = COUNT(*) FROM table2 WHERE champ1 = @critere1 and champ2 = @critere2 and champ3 = @critere3 and state = 'etat2'
    IF @total_numeros_etat2_table = 1
    	BEGIN
    		SET @total_numeros_etat2_table_tmp = @total_numeros_etat2_table_tmp + 1
    END
    /* ---------------------------------------------------------SELECT 4 ---------------------------------------------------------------------------*/
    SELECT DECLARE @total_numeros1_etat1_table = COUNT(*) FROM table2 WHERE champ1 = 'XXXXX' and champ2 = @critere2 and champ3 = @critere3 and state = 'etat1'
    IF DECLARE @total_numeros1_etat1_table = 1
    	BEGIN
    		SET DECLARE @total_numeros1_etat1_table_tmp = DECLARE @total_numeros1_etat1_table_tmp + 1
     
    END
    /* ---------------------------------------------------------SELECT 5 ---------------------------------------------------------------------------*/  
    SELECT @total_numeros1_etat2_table = COUNT(*) FROM table2 WHERE champ1 = @critere1 and champ2 = @critere2 and champ3 = @critere3 and state = 'etat2'
     
    IF @total_numeros1_etat2_table = 1 
      BEGIN
     
          SET @total_numeros1_etat2_table_tmp = @total_numeros1_etat2_table_tmp + 1 
     
      END
    FETCH NEXT FROM champs_a_decoder_cursor INTO @valeur_a_decoder
    END
    CLOSE champs_a_decoder_cursor
    DEALLOCATE champs_a_decoder_cursor
    PRINT  '-------------- End -------------'

    Merci

  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 : 44
    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
    Par défaut
    Bonjour,

    Tout d'abord plusieurs remarques par rapport à votre code :

    - Bannissez l'utilisation de curseurs autant que cela est possible, en les remplaçant par des requêtes qui traitent des ensembles de données.
    SQL est un langage qui est conçu pour cela, et non pas pour des traitement itératifs, comme ceux imposés par l'utilisation de curseurs.
    Ne les utilisez qu'en dernier recours, c'est-à-dire après avoir exploré toutes les autres solutions offertes par SQL et SQL Server plus particulièrement (expressions de table commune, vues, ...).
    En plus de cela ils sont extrêmement lents et coûteux en ressources système, notamment dans l'utilisation de la base de données TempDB, dont SQL Server se sert pour bien d'autres tâches .
    Pour vous en convaincre, vous pouvez lire le petit billet que j'ai écrit à ce sujet

    - Bannissez également l'utilisation de tables temporaires, qui elles aussi sont inutiles et contre-performantes. Vous pouvez là-aussi lire un petit billet où je traite ce fléau.

    - Indentez votre code, cela le rend plus lisible

    - Pensez à l'utilisation de la balise code lorsque vous postez (le bouton #)

    Donnez la commande T-SQL qui permet de créer les tables dont vous vous servez dans votre lot de requêtes (clic-droit sur la table | générer le script de la table en tant que ...| CREATE)

    Il est dommage que vous n'ayez pas précisé ce pour quoi vous avez besoin de faire un tel traitement : dans votre lot on ne voit pas ce que vous faites ensuite, il manque un bout de code.
    Si vous nous le fournissiez, je pense que nous pourrons résoudre votre problème en une seule requête

    Au début de votre code, vous avez écrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SET @End_Period_Date = '20090803235959'
    S'il est bien d'avoir respecté la norme ISO de notation des dates, vous pouvez remplacer cette écriture par la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SET @End_Period_Date = '20090804'
    De plus je viens de tester l'affectation de la variable comme vous l'avez écrit, et celle-ci produit l'erreur suivante :

    Msg*241, Niveau*16, État*1, Ligne*2
    Échec de la conversion d'une valeur datetime à partir d'une chaîne de caractères.
    Je doute donc que vous vous serviez de cela pour faire fonctionner la suite du lot.

    Si nous écrivons :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DECLARE @Start_Period_Date DATETIME
    SET @Start_Period_Date = '20090803 23:59:59'
    SELECT @Start_Period_Date
     
    SET @Start_Period_Date = '20090804'
    SELECT @Start_Period_Date
    Cela fonctionne et nous obtenons deux dates qui sont séparées d'une seconde. Je suppose que vous pouvez utiliser 20090804

    Je vous propose une amélioration de votre code :

    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
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    DECLARE @valeur_a_decoder VARCHAR(100),
    		 @critere1 VARCHAR(100),
    		 @critere2 INT,
    		 @critere3 INT,
    		 @total_numeros_etat1_table2 INT,
    		 @total_numeros_etat1_table INT,
    		 @total_numeros_etat1_table_tmp INT,
    		 @total_numeros_etat2_table INT,
    		 @total_numeros_etat2_table_tmp INT,
    		 @total_numeros1_etat1_table INT,
    		 @total_numeros1_etat1_table_tmp INT,
    		 @total_numeros1_etat2_table INT,
    		 @total_numeros1_etat2_table_tmp INT,
    		 @Start_Period_Date VARCHAR(300),
    		 @End_Period_Date VARCHAR(300)	
     
    SELECT @Start_Period_Date = '20090101',
    		@End_Period_Date = '20090804'
     
    --------------------------
    -- SET TEMPORARY VARIABLES
    --------------------------
    SELECT @total_numeros_etat1_table_tmp = 0,
    		@total_numeros_etat2_table_tmp = 0,
    		@total_numeros1_etat1_table_tmp = 0,
    		@total_numeros1_etat2_table_tmp = 0
     
    DECLARE champs_a_decoder_cursor CURSOR FOR
    	SELECT champs_a_decoder
    	FROM dbo.table
    	WHERE champs1 = 'status'
    	AND operation_date >= @Start_Period_Date
    	AND operation_date <= @End_Period_Date
    	AND error_text = 'status'
    FOR READ ONLY
     
    OPEN champs_a_decoder_cursor
    FETCH NEXT FROM champs_a_decoder_cursor INTO @valeur_a_decoder
    WHILE @@FETCH_STATUS = 0
    BEGIN
    	SELECT @critere1 = SUBSTRING(@valeur_a_decoder, 7, 1),
    			@critere2 = SUBSTRING(@valeur_a_decoder, 8, 3),
    			@critere3 = SUBSTRING(@valeur_a_decoder, 11, 5)
     
    	SELECT CASE @critere1
    				WHEN 1 THEN 'XXXXX'
    				ELSE 'YYYYY'
    			END
     
    	-----------
    	-- SELECT 1
    	-----------
    	SELECT @total_numeros_etat1_table2 = COUNT(*)
    	FROM dbo.table2
    	WHERE champ1 = @critere1
    	AND champ2 = @critere2
    	AND champ3 = @critere3
    	AND state = 'etat1'
     
    	IF @total_numeros_etat1_table2 = 1
    	BEGIN
    		SET @total_numeros_etat1_table2_tmp = @total_numeros_etat1_table2_tmp + 1
    	END
     
    	-----------
    	-- SELECT 2
    	-----------
    	SELECT @total_numeros_etat1_table = COUNT(*)
    	FROM dbo.table2
    	WHERE champ1 = 'YYYYY' 
    	AND champ2 = @critere2
    	AND champ3 = @critere3
    	AND state = 'etat1'
     
    	IF @total_numeros_etat1_table_tmp = 1
    	BEGIN
    		SET @total_numeros_etat1_table_tmp = @total_numeros_etat1_table_tmp + 1
    	END
     
    	-----------
    	-- SELECT 3
    	-----------
    	SELECT @total_numeros_etat2_table = COUNT(*)
    	FROM dbo.table2
    	WHERE champ1 = @critere1
    	AND champ2 = @critere2
    	AND champ3 = @critere3
    	AND state = 'etat2'
     
    	IF @total_numeros_etat2_table = 1
    	BEGIN
    		SET @total_numeros_etat2_table_tmp = @total_numeros_etat2_table_tmp + 1
    	END
     
    	-----------
    	-- SELECT 4
    	-----------
    	SELECT @total_numeros1_etat1_table = COUNT(*)
    	FROM dbo.table2
    	WHERE champ1 = 'XXXXX'
    	AND champ2 = @critere2
    	AND champ3 = @critere3
    	AND state = 'etat1'
     
    	IF @total_numeros1_etat1_table = 1
    	BEGIN
    		SET @total_numeros1_etat1_table_tmp = @total_numeros1_etat1_table_tmp + 1
    	END
     
    	-----------
    	-- SELECT 5
    	-----------
    	SELECT @total_numeros1_etat2_table = COUNT(*)
    	FROM dbo.table2
    	WHERE champ1 = @critere1
    	AND champ2 = @critere2
    	AND champ3 = @critere3
    	AND state = 'etat2'
     
    	IF @total_numeros1_etat2_table = 1
    	BEGIN
    		SET @total_numeros1_etat2_table_tmp = @total_numeros1_etat2_table_tmp + 1
    	END
     
    	FETCH NEXT FROM champs_a_decoder_cursor INTO @valeur_a_decoder
    END
     
    DEALLOCATE champs_a_decoder_cursor
    PRINT '-------------- End -------------'
    Mais je reste persuadé que nous pouvons nous passer de ce curseur

    @++

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 2
    Par défaut
    Bonjour,

    Merci bcp pour vos conseilles qui m'ont énormement servis.

    J'ai réecris la rêquete avec votre methode effectivement elle est plus lisible et compréhensible mais je trouve tjr des doublons avec les mêmes critéres
    pourtant j'ai bien vérifier qu'il n'y en a pas dans dans les tables source et ma table de comparaison.


    Merci

Discussions similaires

  1. [AC-2007] Problème requête count dans VBA ACCESS
    Par carophil dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 02/06/2010, 16h11
  2. Problème du count dans une relation ManyToMany
    Par Invité dans le forum Général Java
    Réponses: 0
    Dernier message: 10/05/2010, 12h58
  3. Problème "count" dans ma requête SQL
    Par Sanaa25 dans le forum Requêtes
    Réponses: 5
    Dernier message: 09/03/2010, 10h34
  4. Problème de count dans un where
    Par Djobird dans le forum Langage SQL
    Réponses: 8
    Dernier message: 03/07/2008, 14h30
  5. Problème de count dans jointure
    Par metfan dans le forum Requêtes
    Réponses: 2
    Dernier message: 07/08/2007, 09h58

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