开发者

Pass a TABLE variable to sp_executesql

I'm trying to pass a TABLE variable to the sp_executesql procedure:

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

 EXEC sp_executesql @sql, @params, @workingData

I get the error:

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

I tried omitting 开发者_如何学Gothe column specification after 'TABLE'. I also tried to declare the table as a variable inside the dynamic SQL. But no luck...

Seems to me that TABLE variables aren't allowed to be passed as parameters in this procedure?. BTW: I'm running MSSQL2008 R2.

I'm not interested in using a local temp table like #workingData because I load the working data from another procedure:

INSERT INTO @workingData
     EXEC myProc @param1, @param2

Which I cannot do directly into a temp varaible (right?)...

Any help appreciated!


If you are using SQL Server 2008, to pass a table variable to a stored procedure you must first define the table type, e.g.:

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

or use an existing table type stored in the database.

Use this query to locate existing table types

SELECT * FROM sys.table_types

To use in an stored procedure, declare an input variable to be the table:

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

END
GO

Populate the table variable before passing to the stored procedure:

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

Call the stored procedure:

EXECUTE usp_myproc
@TableVariable = @DataTable

Further discussions here.


OK, this will get me what I want, but surely isn't pretty:

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

There must be a better way to pass this temporary resultset into sp_executesql!?

Regards Alex


While this may not directly answer your question, it should solve your issue overall.

You can indeed capture the results of a Stored Procedure execution into a temporary table:

INSERT INTO #workingData
EXEC myProc 

So change your code to look like the following:

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    

Regards, Tim


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

Please note that the above code will not work as table as a object is out of the scope.It will give you the error: must declare table variable.In order to work around we can do the following.

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


So-called TableType is tricky. @Alex version should work. However, to simplify and faster performance, go check sys.tables for matching table name while not compromise security and performance.

Here it is

create proc [dbo].Test11 
@t1 AS nvarchar(250), @t2 nvarchar(250)
AS 
BEGIN
SET nocount ON; 
DECLARE @query AS nvarchar(MAX)
if exists (select * from sys.tables where name = @t1) and 
    exists (select * from sys.tables where name = @t2)
begin
    SET @query = N'select * FROM '+ @t1 + N' join ' + @t2 + N' ON ...' ;
    select 'Safe and fast'
    print @query
    exec sp_executesql @query

end
else
    select 'Bad, no way Jose.'

SET nocount OFF; 
END
GO
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜