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年是这样。