1

我创建了一个临时表变量,然后我需要对其进行旋转:

Declare @TempTable TABLE(
Name varchar(150),
CloseDate Date, 
Revenue Float)

.... <add data to it> .....    

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(CloseDate) 
            FROM @TempTable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT  Name, ' + @cols + ' from 
                (select 
                    t.Name,
                    t.CloseDate,
                    t.Revenue
                from @TempTable as t
                ) x
            pivot 
                (SUM(Revenue)
                    for CloseDate in (' + @cols + ')
                ) p '

execute(@query)

但是,我收到此错误:

Must declare the scalar variable "@TempTable".

当我使用普通的 SELECT 测试 @TempTable 变量时,它工作正常:

SELECT * from @TempTable

如何在查询字符串中成功引用变量?

4

1 回答 1

5

不幸的是,当您使用 execute 和 sp_executesql 时,它们在自己的上下文中运行,因此它们无法引用在动态 SQL 范围之外定义的表变量对象。

在这种情况下,我倾向于创建一个临时表,并在 tempdb 中创建的临时表的名称中嵌入一个 GUID。这确保了表名对于同时操作是唯一的,然后我将该 guid 放在创建的动态 SQL 中。

性能方面,它稍慢但仍然很快,但这是否对您来说是个问题取决于执行的次数和频率。

在对此答案的评论中与 Damien 进行了一些讨论后,我们确定在执行动态 SQL 时可以使用本地临时表(单个标签)。

因此,如果您将声明表变量更改为 CREATE TABLE #TempTable 并更改动态 SQL 中的引用,这应该适合您。

如果您的调用代码使用某种形式的连接池,我对使用临时表的唯一担忧是对象的持久性,这听起来不像这里的情况。

但是,作为一般的自我偏执的自我实践,我喜欢在创建表之前和语句末尾抛出其中一个以清理对象。

IF OBJECT_ID(N'tempdb..#TempTable') IS NOT NULL
DROP TABLE #TempTable

CREATE TABLE #TempTable (Value VARCHAR(50));
于 2013-11-11T15:18:57.773 回答