动态SQL结果INTO临时表

时间:2015-01-03 06:18:02

标签: sql sql-server sql-server-2008-r2 sql-server-2012

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

动态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 ;'

     --@Cols => Column Names which varies in number

现在我必须将动态sql结果插入到#Temp表中,并将此#Temp表与另一个现有表一起使用来执行连接或其他操作。

#Temp表应存在于其中以执行与其他现有表的操作)

如何将动态SQL查询结果插入临时表?

由于

5 个答案:

答案 0 :(得分:0)

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

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

"select * from table" dyanmic query 。这将返回结果,您可以将其用作示例中给出的temp table t1

答案 1 :(得分: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

答案 2 :(得分: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表,并仅使用其中一些(使所有列都为NULL)。

因此,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)自然会在存储过程中。

答案 3 :(得分: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 

答案 4 :(得分:0)

以下是您的问题的逐步解决方案。

  1. 检查您的临时表(如果存在),并将其删除。
  2. IF OBJECT_ID('tempdb..#temp') IS NOT NULL
    DROP TABLE #temp
    
    IF OBJECT_ID('tempdb..##abc') IS NOT NULL
    DROP TABLE ##abc
    
    1. 将您的主查询结果存储在第一个临时表中(此步骤是为了简化和提高可读性)。
    2. 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
      


      1. 编写以下查询以创建pivot并将结果存储在另一个临时表中。
      2. 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'
        
        1. 执行以下查询,以便在下一个temp table ##abc 中获取数据结果。
        2.   

          EXECUTE sp_executesql @sql

          1. 现在你可以使用##abc作为你想要的表格
          2.   

            select * from ##abc

            希望这会对你有所帮助。