web-dev-qa-db-fra.com

Passer une variable TABLE à sp_executesql

J'essaie de passer une variable TABLE à la procédure sp_executesql:

 DECLARE @params NVARCHAR(MAX)
 SET @params = '@workingData TABLE ( col1 VARCHAR(20),
                col2 VARCHAR(50) )'

 EXEC sp_executesql @sql, @params, @workingData

Je reçois l'erreur: 

Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'TABLE'.

J'ai essayé d'omettre la spécification de colonne après «TABLE». J'ai également essayé de déclarer la table en tant que variable à l'intérieur du SQL dynamique. Mais pas de chance ...

Il me semble que les variables TABLE ne peuvent pas être transmises en tant que paramètres dans cette procédure ?. BTW: J'exécute MSSQL2008 R2.

L'utilisation d'une table temporaire locale telle que #workingData ne m'intéresse pas car je charge les données de travail à partir d'une autre procédure:

INSERT INTO @workingData
     EXEC myProc @param1, @param2

Ce que je ne peux pas faire directement dans un emploi du temps (non?) ...

Toute aide appréciée!

22
Alex

Si vous utilisez SQL Server 2008, pour passer une variable de table à une procédure stockée, vous devez d'abord définir le type de table, par exemple:

CREATE TYPE SalesHistoryTableType AS TABLE
(                     
    [Product] [varchar](10) NULL,                
    [SaleDate] [datetime] NULL,                
    [SalePrice] [money] NULL
)
GO

ou utilisez un type de table existant stocké dans la base de données.

Utilisez cette requête pour localiser les types de table existants 

SELECT * FROM sys.table_types

Pour l'utiliser dans une procédure stockée, déclarez une variable d'entrée comme étant la table:

CREATE PROCEDURE usp_myproc
(
    @TableVariable SalesHistoryTableType READONLY
)
AS BEGIN
    --Do stuff     

END
GO

Renseignez la variable de table avant de la transmettre à la procédure stockée:

DECLARE @DataTable AS SalesHistoryTableType
INSERT INTO @DataTable
SELECT * FROM (Some data)

Appelez la procédure stockée:

EXECUTE usp_myproc
@TableVariable = @DataTable

Discussions ultérieures ici .

12
Gary Kindel

OK, ça va me donner ce que je veux, mais ce n’est sûrement pas joli:

DECLARE @workingData TABLE ( col1 VARCHAR(20),
        col2 VARCHAR(20) )

    INSERT INTO @workingData
        EXEC myProc

    /* Unfortunately table variables are outside scope
       for the dynamic SQL later run. We copy the 
       table to a temp table. 
       The table variable is needed to extract data directly
       from the strored procedure call above...
    */
    SELECT * 
    INTO #workingData
    FROM @workingData


        DECLARE @sql NVARCHAR(MAX)
    SET @sql = 'SELECT * FROM #workingData'

    EXEC sp_executesql @sql

Il doit exister un meilleur moyen de passer cet ensemble de résultats temporaire dans sp_executesql !?

Cordialement Alex

3
Alex

Bien que cela ne réponde pas directement à votre question, cela devrait résoudre votre problème dans son ensemble.

Vous pouvez en effet capturer les résultats d'une exécution de procédure stockée dans une table temporaire:

INSERT INTO #workingData
EXEC myProc 

Alors changez votre code pour ressembler à ceci:

CREATE TABLE #workingData ( col1 VARCHAR(20),    
    col2 VARCHAR(20) )    

INSERT INTO #workingData    
    EXEC myProc    

DECLARE @sql NVARCHAR(MAX)    
SET @sql = 'SELECT * FROM #workingData'    

EXEC sp_executesql @sql    

Cordialement, Tim

2
Tim Friesen
Alter PROCEDURE sp_table_getcount 
 @tblname nvarchar(50) ,
 @totalrow int output 
AS
BEGIN

Declare @params nvarchar(1000)
Declare @sql nvarchar(1000)
set @sql = N'Select @cnt= count(*) From @tbl'
set @params = N'@tbl nvarchar(50) , @cnt int OUTPUT'
Exec sp_executesql @sql , @params ,@tbl=@tblname ,  @cnt = @totalrow OUTPUT   
END
GO

Veuillez noter que le code ci-dessus ne fonctionnera pas comme une table car un objet est en dehors de la portée. Il vous donnera le message d'erreur suivant: doit déclarer une variable de table.Pour contourner le problème, nous pouvons procéder comme suit.

Alter PROCEDURE sp_table_getcount 
 @tblname nvarchar(50) ,
 @totalrow int output 
AS
BEGIN

Declare @params nvarchar(1000)
Declare @sql nvarchar(1000)
set @sql = N'Select @cnt= count(*) From dbo.' + @tblname
set @params = N'@cnt int OUTPUT'
Exec sp_executesql @sql , @params , @cnt = @totalrow OUTPUT   
END
GO
0
kta