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 :

Appeller Fonction en tant que parametre


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 20
    Par défaut Appeller Fonction en tant que parametre
    Bonjour à tous

    Je me permets de vous solliciter pour un problème de fonction table sous T-SQL. N'étant pas un spécialiste je bloque sur un point particulier :

    J'ai créé une fonction table qui prend en entrée 5 parametres.
    Lors de la construction de cette table, dans le corps de la fonction, je fais un moment une jointure de type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    table.nomchamp = ( select * from UneAutreFonction(param1, param2, param3))
    Pour l'instant tout va bien et tout cela fonctionne.

    Il se trouve que param2 de cette fonction appellée est le même que celui saisit en parametre de ma fonction principale.

    Mon soucis est que j'aimerai faire un test sur ce parametre de type, si sa valeur est nulle, j'appelle une autre fonction qui me renvoi un numeric et ainsi prendre cette valeur à la place. J'ai essayé avec isnull mais il n'aime pas se retrouver avec un select en 2e argument.

    Il me suffirait, je pense, d'affecter le résultat de cette "UneAutreFonction" dans une variable mais étant dans une fonction table, rien n'y fait je n'arrive pas à déclarer une toute bete variable....

    J'en appelle donc à vos connaissances afin de m'aiguiller, sachant que ma fonction table fonctionne très bien mis à part ce controle que je n'arrive pas à effectuer.

    Ma fonction présente cette structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE FUNCTION [ZDD].[SYS_Func] 
    (
    @Pram	AS NUMERIC(3)		  =  	NULL	
    ...
    )
    RETURNS TABLE
    AS
    RETURN
    (
           mon select
    )
    Merci d'avance

  2. #2
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 20
    Par défaut
    Autre piste:

    Je ne sais pas dans quelle mesure c'est possible mais une solution consisterait, lors de la déclaration du parametre de la fonction, de lui affecter une valeur pas défaut correspondant à la valeur retournée par "UneAutreFonction"....

    Je ne sais pas si c'est faisable.

    Merci d'avance

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

    Globalement ce que vous faites sera forcément contre-performant.
    Je pense que vous confondez fonction et procédure stockée.

    Voici néanmoins ce que vous pouvez écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    TABLE.nomchamp IN
    (
    	SELECT	*
    	FROM	dbo.UneAutreFonction(param1, ISNULL(param2, dbo.AnotherFunction(param2), param3)
    )
    Dans votre code original :

    - vous n'avez pas qualifié la fonction UneAutreFonction par le nom du schéma auquel elle appartient, ce qui oblige SQL Server à aller le chercher dans les tables de métadonnées pour le comparer ensuite à l'exécutant ...

    - vous utilisez * ce qui oblige SQL Server une nouvelle fois à rechercher dans les tables de métadonnées la structure de la table retournée par votre fonction, avec les types des colonnes ... mieux vaut utiliser le nom de la colonne.
    * ne doit être utilisé que pour un COUNT() ou pour EXISTS, ces deux primitives étant optimisées pour cela

    @++

  4. #4
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 20
    Par défaut
    Tout d'abord merci beaucoup pour l'intérêt que vous portez à mon problème.

    J'ai finalement résolu mon problème en passant par une fonction table à instructions multiples ce qui m'a permis d'affecter le résultat de ma fonction à une variable.
    Par contre j'aimerais revenir sur vos remarques

    - vous n'avez pas qualifié la fonction UneAutreFonction par le nom du schéma auquel elle appartient, ce qui oblige SQL Server à aller le chercher dans les tables de métadonnées pour le comparer ensuite à l'exécutant ...
    Effectivement mais dans la réalité c'est le cas. Je suis allé un peu vite en tapant l'extrait de ma fonction.

    - vous utilisez * ce qui oblige SQL Server une nouvelle fois à rechercher dans les tables de métadonnées la structure de la table retournée par votre fonction, avec les types des colonnes ... mieux vaut utiliser le nom de la colonne.
    * ne doit être utilisé que pour un COUNT() ou pour EXISTS, ces deux primitives étant optimisées pour cela
    Je n'utilise pas d'étoile, peut être faites vous référence aux "..." qui signifiaient : il y a plein de code qui suit.... ^^

    Par contre j'ignorais que COUNT et EXISTS étaient optimisés pour "*". Merci pour l'information.

    Concernant votre remarque sur le fait d'utliser plutôt une procédure, pourriez vous m en dire un peu plus s'il vous plaît?
    En effet la finalité de ma fonction est d'être appellée sous Excel pour des sortes de mécanismes de controle des données. Elle ne fait que lire ces données. Je pensais donc que la fonction était à privilégier mais si vous m'en dites plus je ne refferai pas l'erreur la prochaine fois.

    Encore merci

  5. #5
    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
    la finalité de ma fonction est d'être appellée sous Excel pour des sortes de mécanismes de controle des données
    Il me semble que SQL Server est suffisament complet pour pouvoir contrôler les données sans avoir recours à Excel

    J'explique ici ce que l'on ne peut pas faire avec une fonction, mais aussi pourquoi.

    En outre, lorsque vous appelez une fonction, quelle que soit son type (scalaire ou retournant une table), elle est évaluée pour chaque ligne de votre résultat sur lequel elle se base.
    Cela va à l'encontre de ce pour quoi sont conçus les moteurs de base de données modernes : traiter des données dans leur ensemble, et non pas ligne à ligne.
    Dès lors, elles ne sont pas performantes.

    Le fait que vous lisiez seulement des données ne justifie pas l'emploi d'une fonction .
    A mon sens tout traitement complexe doit être effectué dans une procédure stockée.

    @++

  6. #6
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 20
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Il me semble que SQL Server est suffisament complet pour pouvoir contrôler les données sans avoir recours à Excel
    Je n'en doute pas mais sur ce point je n'ai pas le choix...

    Citation Envoyé par elsuket Voir le message
    J'explique ici ce que l'on ne peut pas faire avec une fonction, mais aussi pourquoi.
    Je vais aller voir ça de ce pas.

    Vos éclaircissements m'ont bien aidé merci!

  7. #7
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 20
    Par défaut
    Citation Envoyé par elsuket Voir le message
    J'explique ici ce que l'on ne peut pas faire avec une fonction, mais aussi pourquoi.
    Sur le lien auquel vous me renvoyez vous dites qu'il n'est pas possible dans une UDF :
    "- d'utiliser des tables temporaires (# et ##)"

    Je ne suis pas sûr de bien comprendre puisque c'est justement ce que j'utilise pour retourner mon résultat. Pourriez vous m'éclairer?

    Merci

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

Discussions similaires

  1. passage de variables en tant que parametre include
    Par touftouf57 dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 27/05/2009, 01h27
  2. Réponses: 3
    Dernier message: 27/01/2008, 21h52
  3. Passage d'une fonction en tant que paramètre
    Par bagnolm dans le forum Langage
    Réponses: 3
    Dernier message: 28/11/2006, 16h58
  4. Réponses: 10
    Dernier message: 28/09/2006, 15h19
  5. Réponses: 2
    Dernier message: 24/08/2006, 18h48

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