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 Scalaire et Clause WHERE


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 19
    Par défaut Fonction Scalaire et Clause WHERE
    Bonjour,

    Je met à jour actuellement un logiciel qui doit déterminer des minutes de communications utilisé sur une carte Fax.

    Il y a une table qui contient des données concernant le tarif d'une zone Fax et une autre stockant des minutes de communication.

    Une zone est déterminé via des opération complexes et plusieurs requêtes. La base ne pouvant être modifié, ce calcul a été déplace du logiciel vers la base en une fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dbo.GetZoneFax(doc.AdresseDest)
    (AdresseDest est un numero de Fax).

    Le gain en utilisant une fonction scalaire lors du calcul a été intéressant.

    Seulement voila. Si je souhaite filtrer sur le résultat de cette fonction dans une WHERE, j'ai un message du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Echec de la conversion de la valeur VARCHAR '00r' en type de donnée in.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT     prod.CodeClient, TB_Zones.ZoneId, TB_Zones.Description, SUM(doc.Durée) AS DuréeFax
    FROM         TB_Prod AS prod INNER JOIN
                          TB_Doc AS doc ON prod.NomProd = doc.NomProd INNER JOIN
                          TB_Zones ON dbo.GetZoneFax(doc.AdresseDest) = TB_Zones.ZoneId
    WHERE  (prod.DateFin < '01/05/2010') AND (prod.DateFin > '01/04/2010') AND (TB_Zones.ZoneId = '01')
    GROUP BY prod.CodeClient, TB_Zones.ZoneId, TB_Zones.Description
    Après de nombreuses vérification je n'ai aucun numéro de fax qui retourne '00r'.

    Si je vire la clause de filtrage (TB_Zones.ZoneId = '01') la requête fonctionne.
    Si j'utilise un HAVING pour garder juste les groupes avec la zone '01', j'obtiens le même problème.

    Mon collègue et moi avons essayé diverses manière de réécrire la requête mais rien n'y fait.

    Et plus bizarre si je met comme clause WHERE (TB_Zones.ZoneId <> '01'), le filtrage marche. Mais avec WHERE NOT (TB_Zones.ZoneId <> '01'), la requête refuse de fonctionner.

    Faire un <> de toute les autres zones, donne le résultat attendu par contre.

    Ce comportement est très bizarre.

    Cordialement

  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 998
    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 998
    Billets dans le blog
    6
    Par défaut
    Commencez par poster le code de la fonction.

    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
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 19
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Commencez par poster le code de la fonction.

    A +
    La voici. Celui ci ne semble fonctionner correctement. c'est une fonction scalaire.

    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
     
    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    GO
    -- =============================================
    -- Description:	<Retourne l'indicatif de zone d'un numero de FAX>
    -- =============================================
    ALTER FUNCTION GetZoneFax (@FaxNum varchar(255)) RETURNS char(2) AS  
    BEGIN
     
    	DECLARE @RES char(2)
     
    	--Le numero maintenant commence par 00
    	IF SUBSTRING(@FaxNum, 1, 2) = '00'
    	BEGIN
    		--Si le 3 eme numero est en 1 on est en plan de numerotation Nord americain
    		IF SUBSTRING(@FaxNum, 3, 1) = '1'
    		BEGIN
    			--On recupere les 4 premiers caracteres pour voir s'il corresponde à un sous zone des USA
    			SELECT @RES = TB_Indicatifs.ZoneId FROM TB_Indicatifs WHERE(TB_Indicatifs.Indicatif = SUBSTRING(@FaxNum, 3, 4))
    			--Si ça ne correspond pas à un code des USA, on retourne la zone des USA standard
    			IF @RES IS NULL 
    			BEGIN
    				SELECT @RES = TB_Indicatifs.ZoneId FROM TB_Indicatifs WHERE(TB_Indicatifs.Indicatif = 1)
    			END
    		END
    		ELSE 
    		BEGIN
    			--On regarde si le 1er numero correspond à une zone
    			SELECT @RES = TB_Indicatifs.ZoneId FROM TB_Indicatifs WHERE(TB_Indicatifs.Indicatif = SUBSTRING(@FaxNum, 3, 1)) 
    			--Si le 1er numero ne correspond pas à une zone on essaye avec 2 numeros
    			IF @RES IS NULL 
    			BEGIN
    				SELECT @RES = TB_Indicatifs.ZoneId FROM TB_Indicatifs WHERE(TB_Indicatifs.Indicatif = SUBSTRING(@FaxNum, 3, 2))
    				--Si les 2 premiers numero ne correspond pas à on on essaye avec 3 numeros
    				IF @RES IS NULL 
    				BEGIN
    					SELECT @RES = TB_Indicatifs.ZoneId FROM TB_Indicatifs WHERE(TB_Indicatifs.Indicatif = SUBSTRING(@FaxNum, 3, 3))
    					--Si les 3 premiers numero ne correspond pas, on retourne le code de zone inconnue
    					IF @RES IS NULL 
    					BEGIN
    						SELECT @RES = TB_Indicatifs.ZoneId FROM TB_Indicatifs WHERE(TB_Indicatifs.Indicatif = 9999)
    					END
    				END
    			END
    		END
    	END
    	ELSE --Cas d'un numero français
    	BEGIN
    		SELECT @RES = TB_Indicatifs.ZoneId FROM TB_Indicatifs WHERE(TB_Indicatifs.Indicatif = 33)
    	END
     
    	RETURN @RES
    END

  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 998
    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 998
    Billets dans le blog
    6
    Par défaut
    Quelle est la description de la table des indicatifs TB_Indicatifs ? N'y aurait-il pas une colonne de type numérique là dedans ????

    En plus je soupçonne que votre problème reprend celui que j'ai exposé ici : http://sqlpro.developpez.com/Exercic...=part-2#LIII-H

    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 averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 19
    Par défaut
    La table Indicatif est compose de 3 colonnes.

    Indicatif, Clef Primaire en INT
    ZoneId (nchar(2))
    Pays nvarchar(Max)

    Je viens de corriger la procedure en rajoutant des conversions vers le type INT mais le resultat est toujours le même.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT @RES = TB_Indicatifs.ZoneId 
    FROM TB_Indicatifs 
    WHERE (TB_Indicatifs.Indicatif = CONVERT(INT,SUBSTRING(@FaxNum, 3, 3)))
    Et en testant sur toute la table avec la totalité des numéro de téléphone j'obtiens toujours un résultat en forme d'integer.

    Pour ce qui est du problème 18, le problème est proche, à la différence que je recherche la plus courte correspondance et que n'aillant que 3 possibilités je ne boucle pas par lisibilité du code.

    Merci pour le problème, je me le garde sous le coude. Il est intéressant.

Discussions similaires

  1. fonction substring dans clause WHERE
    Par cnidaire dans le forum DB2
    Réponses: 1
    Dernier message: 24/11/2011, 10h21
  2. Lenteur à l'utilisation d'une fonction dans une clause WHERE
    Par lacombefr dans le forum Développement
    Réponses: 2
    Dernier message: 06/04/2010, 19h50
  3. Problème avec fonction "Now" dans clause Where
    Par moilou2 dans le forum VBA Access
    Réponses: 3
    Dernier message: 10/07/2008, 18h44
  4. Fonction déterministe dans clause where
    Par McFoggy dans le forum SQL
    Réponses: 1
    Dernier message: 24/06/2007, 20h46
  5. [8.i]Fonctions dates et clause Where
    Par jdotti dans le forum Oracle
    Réponses: 6
    Dernier message: 03/08/2006, 18h07

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