正如在(https://social.msdn.microsoft.com/Forums/sqlserver/en-US/144f0812-b3a2-4197-91bc-f1515e7de4b9/not-able-to-create-hash-table-inside-stored-proc-through-execute-spexecutesql-strquery?forum=sqldatabaseengine)回答,
你需要事先创建一个#TEMP表:
CREATE TABLE #Temp(columns definition);
看来这个任务是不可能的,如果你一无所知列提前的动态列表。但是,很可能你确实知道一些事情。
您知道动态列的类型,因为它们来自PIVOT
。最有可能的是,您知道动态列的最大可能数量。即使您不这样做,SQL Server每个(非全域)表的限制为1024列,并且每行限制为8060个字节(http://msdn.microsoft.com/en-us/library/ms143432.aspx)。因此,您可以事先创建一个#Temp表,并使用最多可能的列数,并只使用其中的一部分(使所有列都可以为空)。
所以,CREATE TABLE
看起来像这样(而不是int
使用你的类型):
CREATE TABLE #Temp(c1 int NULL, c2 int NULL, c3 int NULL, ..., c1024 int NULL);
是,在#TEMP列名不一样@Cols
。你的处理应该没问题。
您有一个列表@Cols
变量中的列。你以某种方式在一些外部代码中创建列的列表,所以当生成@Cols
时,你知道有多少列。此时,您应该能够生成与#Temp的定义匹配的第二列列表。喜欢的东西:
@TempCols = N'c1, c2, c3, c4, c5';
列的@TempCols
数量应该是一样列在@Cols
数量。那么你的动态SQL是这样的(我已经在你的代码前面加INSERT INTO #Temp (@TempCols)
):
SET @Sql = N'INSERT INTO #Temp (' + @TempCols + N') SELECT ' + @Cols + N' FROM
(
SELECT ResourceKey, ResourceValue
FROM LocaleStringResources where StateId ='
+ LTRIM(RTRIM(@StateID)) + ' AND FormId =' + LTRIM(RTRIM(@FormID))
+ ' AND CultureCode =''' + LTRIM(RTRIM(@CultureCode)) + '''
) x
pivot
(
max(ResourceValue)
for ResourceKey IN (' + @Cols + ')
) p ;'
然后你执行你的动态SQL:
EXEC (@Sql) OR sp_executesql @Sql
然后做使用#Temp
表中的其他处理和临时列名c1, c2, c3, ...
MSDN says:
在存储过程中创建的本地临时表将在存储过程完成时自动删除 。
您还可以DROP
#temp表明确,像这样:
IF OBJECT_ID('tempdb..#Temp') IS NOT NULL
DROP TABLE #Temp'
所有这些T-SQL代码(CREATE TABLE
,EXEC
,...您的自定义处理......,DROP TABLE
)将自然会在存储过程中。
请显示您的查询,直到现在您还在尝试什么 – Hitesh
@Hitesh .. ses更新了数据库。 –
@Cols数据类型的值是什么? @ user3879765 –