如何在动态sql语句中使用表变量?

Ash*_*yed 61 sql sql-server dynamic-sql table-variable sql-server-2008

在我的存储过程中,我在我的过程之上声明了两个表变量.现在我试图在动态sql语句中使用该表变量,但是在执行该过程时出现此错误.我正在使用Sql Server 2008.

这是我的查询的样子,

set @col_name =  'Assoc_Item_' 
              + Convert(nvarchar(2), @curr_row1);

set @sqlstat = 'update @RelPro set ' 
             + @col_name 
             + ' = (Select relsku From @TSku Where tid = ' 
             + Convert(nvarchar(2), @curr_row1) + ') Where RowID = ' 
             + Convert(nvarchar(2), @curr_row);

Exec(@sqlstat);
Run Code Online (Sandbox Code Playgroud)

我得到以下错误,

必须声明表变量"@RelPro".必须声明表变量"@TSku".

我试图在动态查询的字符串块之外取表,但无济于事.

Mar*_*ith 78

在SQL Server 2008+上,只要您不需要更新表本身中的值,就可以使用表值参数将表变量传递给动态SQL语句.

所以从你发布的代码中你可以使用这种方法,@TSku但不是@RelPro

示例语法如下.

CREATE TYPE MyTable AS TABLE 
( 
Foo int,
Bar int
);
GO


DECLARE @T AS MyTable;

INSERT INTO @T VALUES (1,2), (2,3)

SELECT *,
        sys.fn_PhysLocFormatter(%%physloc%%) AS [physloc]
FROM @T

EXEC sp_executesql
  N'SELECT *,
        sys.fn_PhysLocFormatter(%%physloc%%) AS [physloc]
    FROM @T',
  N'@T MyTable READONLY',
  @T=@T 
Run Code Online (Sandbox Code Playgroud)

physloc包含该列只是为了证明子作用域中引用的表变量绝对与外部作用域而不是副本相同.


Joe*_*lli 62

您的EXEC在不同的上下文中执行,因此它不知道在原始上下文中声明的任何变量.您应该能够使用临时表而不是表变量,如下面的简单演示所示.

create table #t (id int)

declare @value nchar(1)
set @value = N'1'

declare @sql nvarchar(max)
set @sql = N'insert into #t (id) values (' + @value + N')'

exec (@sql)

select * from #t

drop table #t
Run Code Online (Sandbox Code Playgroud)

  • @John不,内部作用域可以看到在父作用域中创建的#table。易于测试。 (2认同)

gbn*_*gbn 14

你不具备使用动态SQL

update
    R
set
    Assoc_Item_1 = CASE WHEN @curr_row = 1 THEN foo.relsku ELSE Assoc_Item_1 END,
    Assoc_Item_2 = CASE WHEN @curr_row = 2 THEN foo.relsku ELSE Assoc_Item_2 END,
    Assoc_Item_3 = CASE WHEN @curr_row = 3 THEN foo.relsku ELSE Assoc_Item_3 END,
    Assoc_Item_4 = CASE WHEN @curr_row = 4 THEN foo.relsku ELSE Assoc_Item_4 END,
    Assoc_Item_5 = CASE WHEN @curr_row = 5 THEN foo.relsku ELSE Assoc_Item_5 END,
    ...
from
    (Select relsku From @TSku Where tid = @curr_row1) foo
    CROSS JOIN
    @RelPro R
Where
     R.RowID = @curr_row;
Run Code Online (Sandbox Code Playgroud)


cod*_*ger 6

您不能这样做,因为表变量超出范围.

您必须在动态SQL语句中声明表变量或创建临时表.

我建议你阅读这篇关于动态SQL的优秀文章.

http://www.sommarskog.se/dynamic_sql.html