2015-01-03 38 views
4

我需要将动态sql结果存储到临时表#Temp动态SQL结果INTO临时表

动态SQL查询结果来自pivot结果,因此列数变化(不固定)。

SET @Sql = N'SELECT ' + @Cols + ' 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 ;' 

    [email protected] => Column Names which varies in number 

现在我要插入动态SQL结果#Temp表和使用该#Temp表与其他现有的表执行连接或别的东西。

#Temp表应该存在有与其他现有表进行操作)

我怎样才能插入动态SQL查询结果到一个临时表?

感谢

+0

请显示您的查询,直到现在您还在尝试什么 – Hitesh

+0

@Hitesh .. ses更新了数据库。 –

+0

@Cols数据类型的值是什么? @ user3879765 –

回答

0

替代创建临时表是使用子查询

select t1.name,t1.lastname from(select * from table)t1. 

其中"select * from table"是你dyanmic query。这将返回结果,你可以用temp table t1作为例子。

0

你可以请尝试下面的查询。

SET @Sql = N'SELECT ' + @Cols + ' 
    into ##TempTable 
    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 ;' 

然后,您可以使用##TempTable进一步操作。

但是,不要忘记砸##TempTable在查询结束,如果你再次运行该查询,它会给你的错误,因为它是一个Global Temporary Table

+1

当相同的查询在另一个会话中运行时,这将失败 –

0

正如在(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 TABLEEXEC,...您的自定义处理......,DROP TABLE)将自然会在存储过程中。

+0

列列表是动态生成的如何期待CREATE TABLE #Temp (列定义)' –

+0

@NoDisplayName,用于在'@ Cols'变量中动态生成列列表的相同过程/函数/方法可用于生成与其类型非常相似的列列表s的语法适合CREATE TABLE语句。如果可以动态生成@Cols ='Column1,Column2,Column3,...',那么可以动态生成'@ColsWithTypes ='Column1 int,Column2 nvarchar(nn),Column3 nvarchar(nn) ,...'',不是吗? –

+1

@NoDisplayName,我错了。我认为我可以'EXEC'' CREATE TABLE#Temp',但现在我意识到,在'EXEC'内创建的这个临时表不会在'EXEC'之外被看到。 –

0
IF OBJECT_ID('tempdb..##TmepTable') IS NOT NULL DROP TABLE ##TmepTable 
    CREATE TABLE ##TmepTable (TmpCol CHAR(1)) 
DECLARE @SQL NVARCHAR(max) =' IF OBJECT_ID(''tempdb..##TmepTable'') IS NOT 
NULL DROP TABLE ##TmepTable 
SELECT * INTO ##TmepTable from [MyTableName]' 
    EXEC sp_executesql @SQL 
SELECT Alias.* FROM ##TmepTable as Alias 

IF OBJECT_ID('tempdb..##TmepTable') IS NOT NULL DROP TABLE ##TmepTable 
0

这是您的问题的一步一步的解决方案。

  1. 检查临时表是否存在,然后删除它们。
IF OBJECT_ID('tempdb..#temp') IS NOT NULL 
DROP TABLE #temp 

IF OBJECT_ID('tempdb..##abc') IS NOT NULL 
DROP TABLE ##abc 
  • 商店中的主要查询结果在第一临时表(此步骤是为了简化和更可读性)。
  • SELECT * 
    INTO #temp 
    FROM (SELECT ResourceKey, ResourceValue 
    FROM LocaleStringResources 
    where StateId ='+ LTRIM(RTRIM(@StateID)) + ' AND FormId =' + LTRIM(RTRIM(@FormID)) 
    + ' AND CultureCode =' + LTRIM(RTRIM(@CultureCode)) + ') AS S 
    


  • 写入下面查询来创建pivot,结果存储在另一个临时表。
  • DECLARE @str NVARCHAR(1000) 
    DECLARE @sql NVARCHAR(1000)  
    SELECT @str = COALESCE(@str+',', '') + ResourceKey FROM #temp 
    
    SET @sql = N'select * into ##abc from (select ' + @str + ' from (SELECT ResourceKey, ResourceValue FROM #temp) as A 
    Pivot 
    ( 
        max(ResourceValue) 
        for ResourceKey in (' + @str + ') 
    )as pvt) as B' 
    
  • 执行以下查询来获取枢轴结果在下次temp table##abc
  • EXECUTE sp_executesql @sql

  • 现在你可以使用##abc为表,其中,任何你想要一个像
  • select * from ##abc

    希望这会帮助你。