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 :

Incompréhension sur une requête


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    310
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 310
    Par défaut Incompréhension sur une requête
    Bonjour,

    voici une 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
    16
    17
    18
     
    SELECT 13309, 'C05' , L.[TxtValeurCle1], L.[TxtValeurCle2], L.[TxtValeurCle3] , L.[NbNumLigne]
    FROM [dbo].[ETL_vLoadLigneOK] L 
    WHERE L.[IdLoadFichier] = 13309 
    AND L.[TxtCodeMouvement] = 'C05' 
    AND ( 
    		SELECT SUM ( CAST (	SUBSTRING ( L2.[TxtLigne], 148,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING( L2.[TxtLigne], 153,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING ( L2.[TxtLigne], 163,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING ( L2.[TxtLigne], 168,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING (L2.[TxtLigne], 173,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING ( L2.[TxtLigne], 178,5)	AS INTEGER ) ) 
    		FROM [dbo].[ETL_vLoadLigneOK] L2 
    		WHERE L2.[IdLoadFichier] = 13309
    		AND	L2.[TxtCodeMouvement] = 'C05'
     
    		AND L2.[TxtValeurCle1] = L.[TxtValeurCle1] ) 
    > 2500
    La SOUS requête plante car il n'arrive pas à convertir une donnée en INTEGER.
    Ces données qu'il n'arrive pas à convertir sont issues de la table mais avec un IdLoadfichier Différent !

    L'erreur est la n°245 impossible de convertir un varchar en integer

    Si j'exécute la requête suivante, il n'y a aucune erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT SUM ( CAST (	SUBSTRING ( L2.[TxtLigne], 148,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING( L2.[TxtLigne], 153,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING ( L2.[TxtLigne], 163,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING ( L2.[TxtLigne], 168,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING (L2.[TxtLigne], 173,5)	AS INTEGER ) ) 
    		+ SUM ( CAST (		SUBSTRING ( L2.[TxtLigne], 178,5)	AS INTEGER ) ) 
    		FROM [dbo].[ETL_vLoadLigneOK] L2 
    		WHERE L2.[IdLoadFichier] = 13309
    		AND	L2.[TxtCodeMouvement] = 'C05'
    Pourtant c'est bien la sous requête qui plante dans le cas précédent.

    Ma question est donc pourquoi ce cas plante alors que ça ne devrait pas à mes yeux.

    Je pourrais modifier la requête afin de l'optimiser (avec un group by + having) mais mon objectif est de comprendre comment cela se fait que SQL Server se foire dans son plan d'exécution ?

    Merci

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour

    Auriez vous un index sur TxtValeurCle1, avec TxtLigne (eventuellement en colonne incluse), mais sans IdLoadFichier ?
    (avec ou sans TxtCodeMouvement)

    Dans ce cas, peut etre que le moteur estime plus rapide d'utiliser cet index et de vérifier que la somme est >2500 avant d'aller chercher la valeur de IdLoadFichier dans la table ?

    Pouvez-vous poster la DDL de la table et de ses index ?

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    310
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 310
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Pouvez-vous poster la DDL de la table et de ses index ?
    Alors il n'y a pas d'index autre que la clé primaire de la table, ainsi que la clé étrangère IdLoadFichier

    les 3 champs TxtvaleurCleX ne sont pas indexés car les données sont génériques et facultatives.

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

    Je pourrais modifier la requête afin de l'optimiser (avec un group by + having) mais mon objectif est de comprendre comment cela se fait que SQL Server se foire dans son plan d'exécution ?
    Non, SQL Server fait les transtypages pour vous parce que vous n'utilisez pas les types de données adaptés à vos besoin.
    Vous pouvez utiliser SSIS pour transformer vos données et les stocker dans une table avec les types de données correspondants.
    Sinon vous pouvez écrire des fonctions qui font les SUBSTRING() à votre place et créer des colonnes calculées.
    En les indexant en plus (sans pour autant les persister), vous devriez avoir des performances correctes.

    Quelle est la valeur que vous retourne la sous-requête lorsque vous l'exécutez seule ?

    @++

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    310
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 310
    Par défaut
    Alors la valeur retournée par la sous requête seule n'a pas de sens en soit car je suis obligé de virer le filtre sur TxtValeurCle1.

    Mais elle renvoie au final le bon chiffre "total" de ce que je recherche.

    par contre une fois remis dans la sous requête ca plante car il n'arrive pas à convertir "030.4" en integer.

    cette valeur "030.4" provient d'une autre ligne de la table mais avec un Idloadfichier différent ...

  6. #6
    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
    Étant donné vous extrayez les des valeurs entières d'une chaîne, il est difficile de s'assurer qu'il n'y a pas un caractère bizarre qui traîne et empêche le transtypage.
    Testez vos SUBSTRING() un à un en filtrant sur l'IdLoadFichier 13309, je suis absolument certain que vous aurez un problème pour l'un d'entre eux.

    @++

Discussions similaires

  1. [WD14] Problème incompréhensible sur une requête
    Par cladoo dans le forum WinDev
    Réponses: 4
    Dernier message: 16/09/2009, 11h42
  2. [Access] Manque d'idées sur une requête
    Par portu dans le forum Langage SQL
    Réponses: 12
    Dernier message: 22/11/2004, 12h25
  3. Pb sur une requête SQL (de champ vide)
    Par Marion dans le forum Langage SQL
    Réponses: 3
    Dernier message: 01/07/2004, 11h12
  4. Problème sur une requête INSERT
    Par Marion dans le forum Langage SQL
    Réponses: 3
    Dernier message: 17/06/2003, 08h45
  5. problème sur une requête!!!!!
    Par Mcgrady_01 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 13/06/2003, 01h17

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