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

MS SQL Server Discussion :

faire un fetch avec le nom d une table comme parametre


Sujet :

MS SQL Server

  1. #1
    Futur Membre du Club
    Inscrit en
    Septembre 2006
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 5
    Points : 5
    Points
    5
    Par défaut faire un fetch avec le nom d une table comme parametre
    Je voudrais passer en parametre d une fonction, le nom d une table pour faire un fetch dessus.
    Malheureusement j'ai une erreur sql.

    Msg 1087, Level 15, State 2, Procedure test, Line 17
    Must declare the table variable "@param_table".


    Le nom des tables qui sont passes en parametres ont la meme structure.


    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    go

    ALTER FUNCTION [dbo].[test] (@param_table VARCHAR(128))
    RETURNS VARCHAR(256)
    AS

    BEGIN
    declare @commentaire varchar(256)
    declare @commentaire1 varchar(256)

    set @commentaire=''
    declare tdesec_cur CURSOR FOR select text from @param_table where code=1 order by sequence;
    open tdesec_cur;
    fetch next FROM tdesec_cur INTO @commentaire;
    while @@FETCH_STATUS =0
    begin
    set @commentaire1=@commentaire1+@commentaire+' '
    fetch next FROM tdesec_cur INTO @commentaire;
    end
    CLOSE tdesec_cur;
    DEALLOCATE tdesec_cur;

    RETURN @commentaire1
    END


    Merci de votre aide.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 434
    Points : 502
    Points
    502
    Par défaut
    Bonjour,

    par quoi est appelé ta fonction ? Une procédure stockée, un code client (VB, C++, ..)

    Si c'est le deuxième cas, je t'invite fortement à faire la concaténation dans le client et pas dans SQL server.

    sinon, essaye ceci en replacant les noms de colonnes et table par tes données. Ca marche en direct, mais je ne sais pas si dans une fonction ca marchera. A voir

    @pRESU contient le resultat de la concatenation, (@commentaire1 dans ton code)
    @pTableName le nom de la table
    @TestVal la chaine à concaténer (@commentaire dans ton 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
     
    declare @SQL nvarchar(4000)
    declare @ptableName nvarchar(4000)
    set @ptableName = 'test'
     
    declare @presu nvarchar(4000)
    set  @presu = ''
     
    declare @ptestVal nvarchar(4000)
    set  @ptestVal = ''
     
     
    set @sql = N'
    declare cur_resu cursor for 
    select TestVal from  ' + @pTableName + '
    OPEN cur_resu 
    fetch next from cur_resu into @testVal 
    while (@@FETCH_STATUS = 0) 
    begin  
    	set @RESU = @RESU + @testVal  + ' ' 
    	fetch next from cur_resu into @testVal 
    End 
    close cur_resu 
    deallocate cur_resu 
    '
     
    DECLARE @Para NVARCHAR(500)
    SET @Para = N'@testVal nvarchar(4000), @RESU nvarchar(4000) OUTPUT'
     
    exec sp_executesql @SQL, @PARA,
    		   @testVal = @pTestVal,
    		   @RESU = @pRESU OUTPUT
     
    select @pRESU

  3. #3
    Membre éprouvé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Août 2006
    Messages
    730
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 730
    Points : 923
    Points
    923
    Par défaut
    directement j'ai pas trouvé, par contre moi je fais:

    - creation d'une table temporaire #tmp
    - @cmd='select text from '+ @param_table+' where code=1 order by sequence'
    - insert into #tmp exec @cmd

    puis je travaille sur la table temporaire: curseur etc...

    ça marche très bien a 1 restriction près qui n'est pas documentée
    ON NE PEUT FAIRE QU'UN SEUL INSERT...EXEC PAR OBJET

  4. #4
    Futur Membre du Club
    Inscrit en
    Septembre 2006
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Merci pour votre aide, malheureusement, je n'ai toujours pas réussi.

    J'appelle ma fonction dans une view sql-server.

    Il me sort comme erreur "Only functions and extended stored procedures can be executed from within a function" Pour la solution de ZERS.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 434
    Points : 502
    Points
    502
    Par défaut
    Salut,

    peux-tu nous donner le code d'appel de la fonction et les modifs apportées que tu as faites ? Parce que tu peux très bien essayer d'éviter d'appeler une fonction et mettre le code proposé dans une procédure stockée, qui récupère en retour la valeur de commentaire !

    Vais voir si on peut pas contourner le soucis

  6. #6
    Futur Membre du Club
    Inscrit en
    Septembre 2006
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Plus de détails.
    J'essaye d'executer un ordre sql dans une fonction, le nom de la table est un paramétre. Cette fonction est appelée dans une ou plusieurs vues.


    Voici l'ordre select de ma vue:

    SELECT CUSTOMER_CODE, dbo.test2 (CUSTOMER_CODE, 'FBNK_CUSTOMER_M8') AS T
    FROM dbo.FBNK_CUSTOMER_M8

    Voila le code de la fonction :

    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    go




    ALTER FUNCTION [dbo].[test2] (@param_table VARCHAR(128),@ptableName VARCHAR(128))
    RETURNS VARCHAR(256)
    AS

    BEGIN

    declare @SQL nvarchar(4000)
    declare @presu nvarchar(4000)
    set @presu = ''



    set @sql = N'
    declare @testval nvarchar(4000)
    set @testval=''
    declare cur_resu cursor for
    select Text from ' + @pTableName + ' where customer_code = @testVal ;
    OPEN cur_resu ;
    fetch next from cur_resu into @testVal
    while (@@FETCH_STATUS = 0)
    begin
    set @RESU = @RESU + @testVal
    fetch next from cur_resu into @testVal
    End
    close cur_resu
    deallocate cur_resu
    '

    DECLARE @Para NVARCHAR(500)
    SET @Para = N'@testVal nvarchar(4000), @RESU nvarchar(4000) OUTPUT'

    exec sp_executesql @SQL, @PARA,
    @testVal = @param_table,
    @RESU = @pRESU OUTPUT

    return @pRESU

    END


    Et malheureusement voila le message d erreur :
    Only functions and extended stored procedures can be executed from within a function.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 434
    Points : 502
    Points
    502
    Par défaut
    OK.

    Je ne vois pas trop l'utilité ici d'utiliser une fonction, puisque si j'ai bien compris, tu veux simplement concaténer, pour un code client donné toutes les valeurs d'un champ d'une table contenant ce code.

    Dàs lors, voici une proc qui te permet de faire ta concaténation dans une table temporaire et te permet de récupérer le résultat. J'ai paramétré la proc pour que tu puisses choisir en entrée la table que tu souhaites parcourir (dbo.FBNK_CUSTOMER_M8 dans ton exemple):

    Attention : il y a une contrainte : c'est que toutes les tables que tu vas utiliser aient tous les colonnes CUSTOMER_CODE et TEXT. Sinon, il faudra aussi paramétrer l'INSERT. C'est plus long à écrire mais guère plus compliqué

    code de la proc :
    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
     
    CREATE procedure spt_concateparcode @pTableName nvarchar(4000)
    AS
     
    BEGIN
     
    CREATE TABLE #RESU (
       CUSTOMER_CODE varchar(128) null,
       COMMENTAIRE nvarchar(3000) null
    )
     
    declare @SQL nvarchar(4000)
     
    set @SQL = '
    INSERT INTO #RESU 
    SELECT DISTINCT CUSTOMER_CODE, ''''
    FROM ' + @pTableName
    EXEC (@SQL)
     
     
    set @sql = N'
    declare cur_resu cursor for 
    select 
    	CUSTOMER_CODE, 
    	TEXT 
    from ' + @pTableName   + ' 
    order by CUSTOMER_CODE
     
    OPEN cur_resu 
     
    fetch next from cur_resu into @customerCode , @commentaire
    while (@@FETCH_STATUS = 0) 
    begin 
     
    	UPDATE #RESU
    	SET COMMENTAIRE = COMMENTAIRE + @commentaire + '' ''
    	WHERE CUSTOMER_CODE = @customerCode 
     
    	fetch next from cur_resu into @customerCode  , @commentaire
    End 
    close cur_resu 
    deallocate cur_resu 
    '
     
    DECLARE @Para NVARCHAR(500)
    SET @Para = N'@customerCode nvarchar(4000), @commentaire nvarchar(4000)'
     
    exec sp_executesql @SQL, @PARA,
    @CustomerCode= '',
    @commentaire = ''
     
    select * from #RESU
     
    DROP TABLE #RESU
    END

    Appel de la proc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    exec spt_concateparcode 'dbo.FBNK_CUSTOMER_M8 '

    jeu d'essai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    1010	630.645.356.1024
    1020	630.660.658.1046
    1325	1055.2556.2020.1999
    1412	1405.265.864.2045
    1412	AABB
    1325	PPPJEYEGHE
    Resu après execution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    1010	630.645.356.1024 
    1020	630.660.658.1046 
    1325	1055.2556.2020.1999 PPPJEYEGHE 
    1412	1405.265.864.2045 AABB

  8. #8
    Futur Membre du Club
    Inscrit en
    Septembre 2006
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Merci
    Merci a Zers pour son efficacité.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 30/12/2008, 18h07
  2. Réponses: 25
    Dernier message: 10/12/2007, 19h28
  3. Réponses: 8
    Dernier message: 15/11/2007, 09h05
  4. Réponses: 2
    Dernier message: 12/07/2006, 16h20
  5. [Access] Nom d'une table avec un espace dans SQL
    Par Corsaire dans le forum Langage SQL
    Réponses: 7
    Dernier message: 21/04/2006, 15h50

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