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 avec parametre table


Sujet :

Développement SQL Server

  1. #1
    Membre régulier

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 52
    Points : 102
    Points
    102
    Par défaut Fonction avec parametre table
    Bonjour,

    J'essaye de réaliser une fonction qui reçoit un paramètre table, et j'ai un message surprenant

    voici un exemple :

    Tout d'abord, créer un type Table et la fonction qui va recevoir ce type

    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
    Create Type tbl_ListeProrata as TABLE
    (
    	Id		varchar(255)	not null,
    	Montant	money		null
    )
    go
     
    Create function dbo.fn_Prorata (@Liste as dbo.tbl_ListeProrata ReadOnly)
    RETURNS @Result TABLE
    (
    	Id		varchar(255)	not null,
    	Montant	money		null,
    	Coeff	decimal(20,17)		null
    )
    AS BEGIN
    	with Toto(Total) as 
    	( Select Total = Sum(IsNull(Montant,0)) from @Liste)
     
    	insert @Result
    	Select L.Id, L.Montant, L.Montant/T.Total  
    	from	@Liste as L, Toto as T
     
    	RETURN
    END
    go
    Puis le test
    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
     
    Create Table #Tata
    (	IdTata	int not null,
    	Montant	money null
    )
     
    Insert into #Tata Values( 1, 158.10)
    Insert into #Tata Values( 2, 780.5)
    Insert into #Tata Values( 3, 980.25)
    Insert into #Tata Values( 4, 1980.25)
    Insert into #Tata Values( 5, 1245)
     
    Declare @AffListe as dbo.tbl_ListeProrata
     
    Insert into @AffListe (Id,Montant)
    Select Id = convert(varchar(255),IdTata), Montant = Montant from #Tata
     
    Select *
    from dbo.fn_Prorata(@AffListe)
    Et Sql Server me répond :
    La variable scalaire "@AffListe" doit être déclarée.
    J'ai beau chercher, je ne vois pas où je faute ...

    Et sur le net, outre Microsoft qui décrit les étapes pour y parvenir complété d'un exemple ... de procédure stocké, je n'ai trouvé que ça voir la réponse de Lukasz Lysik du Oct 22 '09 at 18:42

    Son exemple tel quel fonctionne, dès que je le transforme pour que la fonction retourne une table, le message revient !

    Est-ce à dire qu'une fonction qui reçoit une table ne peut pas en renvoyer elle même une ?

  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 : 42
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Je viens de faire le test sur mon instance SQL Server 2008 R2, et en fait votre erreur n'est pas dans le code mais dans la façon dont vous l'exécutez manuellement.

    Vous avez dû exécuter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE TABLE #Tata
    (	IdTata	int NOT NULL,
    	Montant	money NULL
    )
     
    INSERT INTO #Tata Values( 1, 158.10)
    INSERT INTO #Tata Values( 2, 780.5)
    INSERT INTO #Tata Values( 3, 980.25)
    INSERT INTO #Tata Values( 4, 1980.25)
    INSERT INTO #Tata Values( 5, 1245)
    Puis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Declare @AffListe AS dbo.tbl_ListeProrata
    comme un instruction seule, en la surlignant et en l'exécutant. Puis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INSERT INTO @AffListe (Id,Montant)
    SELECT Id = convert(varchar(255),IdTata), Montant = Montant FROM #Tata
     
    SELECT *
    FROM dbo.fn_Prorata(@AffListe)
    Ce qui fait que la variable @AffListe n'existe plus : elle n'a d'existence que pour la durée du lot de requêtes que vous soumettez.

    En outre je ne vous conseille pas d'utiliser le type de données money, qui produit des erreurs de calculs bien connues.
    Utilisez le type decimal.

    @++

  3. #3
    Membre régulier

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 52
    Points : 102
    Points
    102
    Par défaut
    Bonjour elsuket, et merci de cette réponse


    Citation Envoyé par elsuket Voir le message
    Bonjour,

    Je viens de faire le test sur mon instance SQL Server 2008 R2, et en fait votre erreur n'est pas dans le code mais dans la façon dont vous l'exécutez manuellement.

    Ce qui fait que la variable @AffListe n'existe plus : elle n'a d'existence que pour la durée du lot de requêtes que vous soumettez.
    Hélas, non, ce n'est pas le cas, le bloc de code est bien exécuter en une seule fois et non par petit bout qui pourrait mettre @AffListe hors course.

    En revanche, si j’exécute le code sans l'appel à la fonction tout se passe correctement, y compris un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select * from @AffListe
    Le pb se situe vraiment à l'appel de la fonction, je suis en SQL 2008 (non R2), je vais essayer de trouver de quoi faire un essai sur R2

    En outre je ne vous conseille pas d'utiliser le type de données money, qui produit des erreurs de calculs bien connues.
    Utilisez le type decimal.
    @++
    OK, merci du rappel, je pratique SQL depuis pas mal d'années, et récemment me suis demandé pourquoi je n'utilisais pas ce type .... j'ai du oublier

    Merci encore, je reviens après avoir essayé sur R2, si j'en trouve un

  4. #4
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Declare @AffListe AS dbo.tbl_ListeProrata
    le AS est simplement de trop...
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  5. #5
    Membre régulier

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 52
    Points : 102
    Points
    102
    Par défaut
    e AS est simplement de trop...
    non plus, avec ou sans rien de mieux ni de moins bien

    Je viens d'essayer sur plusieurs machines, certaines passent d'autre non, et ce n'est pas une question de version puisque sur un site, j'ai deux machines avec versions identiques (2007.100.1600.022) l'une passait, l'autre non.
    Plus surprenant, sur ces 2 machines, le serveur ne passait pas et l'autre -machine de dev en seven 64 - passait.

    J'avoue que je n'y comprends plus rien.
    Une histoire de paramétrage ?

  6. #6
    Membre régulier

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 52
    Points : 102
    Points
    102
    Par défaut
    J'ai effectué le test sur différentes configurations
    constats :

    > Fonction recevant une table en paramètre et renvoyant un varchar - RAS
    > Fonction recevant un varchar en paramètre et renvoyant une table - RAS
    > Fonction recevant une table en paramètre et renvoyant une table
    - 2008 Standard 64 (10.0.1600) NOK
    - 2008 Standard 64 (10.0.2573) NOK
    - 2008 Developper 64 (10.0.1600) OK
    - 2008 Standard 64 (10.0.4000) OK
    - 2008 Standard 32 (10.0.4064) NOK
    - 2008 R2 Express 32 (10.50.1617.0) OK


    Etonnant non ?

    Si quelqu'un avait une explication ...

Discussions similaires

  1. [EasyPHP] Fonction avec parametre par référence et EasyPHP 1.8
    Par niaxon dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 9
    Dernier message: 01/02/2007, 10h59
  2. Fonction avec parametre variable
    Par Linaa dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 17/12/2006, 12h41
  3. appel d'une fonction avec parametre.
    Par rollernox dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 12/10/2006, 23h07
  4. créer une fonction avec parametre optionnel
    Par maximenet dans le forum Langage
    Réponses: 2
    Dernier message: 29/01/2006, 20h51
  5. fonction avec parametre
    Par donny dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/06/2005, 11h31

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