Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在查询字符串中引用表变量_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 在查询字符串中引用表变量

Sql 在查询字符串中引用表变量,sql,sql-server,tsql,Sql,Sql Server,Tsql,我已经创建了一个临时表变量,然后需要对其进行透视: Declare @TempTable TABLE( Name varchar(150), CloseDate Date, Revenue Float) .... <add data to it> ..... SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(CloseDate) FROM @TempTable FOR

我已经创建了一个临时表变量,然后需要对其进行透视:

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)
当我使用普通选择测试@tentable变量时,它工作正常:

SELECT * from @TempTable

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

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

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

性能方面,它稍微慢一点,但仍然很快,但这是否是您的问题,取决于执行的次数和频率

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

因此,如果您将declare table变量更改为CREATE table#tentable,并更改动态SQL中的引用,那么这对您来说应该可以正常工作

关于使用临时表,我唯一关心的是,如果调用代码使用某种形式的连接池,那么对象的持久性问题,这听起来不像这里的情况

然而,作为一种普遍的自我偏执的自我实践,我喜欢在create表之前和语句末尾抛出其中一个来清理对象

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

CREATE TABLE #TempTable (Value VARCHAR(50));

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

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

性能方面,它稍微慢一点,但仍然很快,但这是否是您的问题,取决于执行的次数和频率

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

因此,如果您将declare table变量更改为CREATE table#tentable,并更改动态SQL中的引用,那么这对您来说应该可以正常工作

关于使用临时表,我唯一关心的是,如果调用代码使用某种形式的连接池,那么对象的持久性问题,这听起来不像这里的情况

然而,作为一种普遍的自我偏执的自我实践,我喜欢在create表之前和语句末尾抛出其中一个来清理对象

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

CREATE TABLE #TempTable (Value VARCHAR(50));

使用“适当”的临时表instead@TI你所说的“适当的”临时表是什么意思?使用“适当的”临时表instead@TI您所说的“正确”临时表是什么意思?无需手动“唯一化”临时表-除非您创建一个全局临时表(此处不需要)临时表名称仅在您自己的连接上必须是唯一的。多个连接可以同时使用具有相同名称的临时表,而不会发生冲突。@Damien_the_unsiver我相信使用EXEC和sp_executesql执行的动态sql不会被视为同一连接的一部分,这将需要使用全局临时表,这就是在本例中使用唯一性的原因。我曾经对此做过一个案例研究,但已经过了几个月了,所以完全有可能是我记错了,或者是值得像SQL2005那样对新版本再次进行测试。
create table#T(ID int not null)exec('insert into#T(ID)values(10)'select*from#T
生成一行,其中包含一列,值为10。正如我所说,这里不需要全局临时表(我的评论也是第一次提到globals)。据我回忆,至少在2000年以前是这样。没有必要手动“唯一化”临时表-除非您创建一个全局临时表(此处不需要),临时表名称只需在您自己的连接上是唯一的。多个连接可以同时使用具有相同名称的临时表,而不会发生冲突。@Damien_the_unsiver我相信使用EXEC和sp_executesql执行的动态sql不会被视为同一连接的一部分,这将需要使用全局临时表,这就是在本例中使用唯一性的原因。我曾经对此做过一个案例研究,但已经过了几个月了,所以完全有可能是我记错了,或者是值得像SQL2005那样对新版本再次进行测试。
create table#T(ID int not null)exec('insert into#T(ID)values(10)'select*from#T
生成一行,其中包含一列,值为10。正如我所说,这里不需要全局临时表(我的评论也是第一次提到globals)。据我回忆,至少在2000年是这样。