简体   繁体   English

动态SQL结果INTO临时表

[英]Dynamic SQL Result INTO Temporary Table

I need to store dynamic sql result into a temporary table #Temp . 我需要将动态sql结果存储到临时表#Temp

Dynamic SQL Query result is from a pivot result, so number of columns varies(Not fixed). 动态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

Now I have to insert dynamic sql result to #Temp Table and use this #Temp Table with another existing table to perform joins or something else. 现在我必须将动态sql结果插入到#Temp表中,并将此#Temp表与另一个现有表一起使用来执行连接或其他操作。

( #Temp table should exist there to perform operations with other existing tables) #Temp表应该存在于那里以执行与其他现有表的操作)

How can I Insert dynamic SQL query result To a Temporary table? 如何将动态SQL查询结果插入临时表?

Thanks 谢谢

Alternative to create a temporary table is to use the subquery 创建临时表的替代方法是使用子查询

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

where "select * from table" is your dyanmic query . 其中"select * from table"是你的dyanmic query which will return result which you can use as temp table t1 as given in example . 这将返回结果,您可以将其用作示例中给出的temp table t1

Can you please try the below query. 您能否尝试以下查询。

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

You can then use the ##TempTable for further operations. 然后,您可以使用##TempTable进行进一步操作。

However, do not forget to drop the ##TempTable at the end of your query as it will give you error if you run the query again as it is a Global Temporary Table 但是,不要忘记在查询结束时删除##TempTable ,因为如果再次运行查询会导致错误,因为它是全局临时表

As was answered in ( 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 ), 正如( https://social.msdn.microsoft.com/Forums/sqlserver/en-US/144f0812-b3a2-4197-91bc-f1515e7de4b9/not-able-to-create-hash-table-inside-存储中的回答-proc-through-execute-spexecutesql-strquery?forum = sqldatabaseengine ),

you need to create a #Temp table in advance: 你需要提前创建一个#Temp表:

CREATE TABLE #Temp(columns definition);

It seems that the task is impossible, if you know nothing about the dynamic list of columns in advance. 如果你事先对列的动态列表一无所知,那么这个任务似乎是不可能完成的。 But, most likely you do know something. 但是,你很可能知道一些事情。

You do know the types of dynamic columns, because they come from PIVOT . 你知道动态列的类型,因为它们来自PIVOT Most likely, you know the maximum possible number of dynamic columns. 最有可能的是,您知道最大可能的动态列数。 Even if you don't, SQL Server has a limit of 1024 columns per (nonwide) table and there is a limit of 8060 bytes per row ( http://msdn.microsoft.com/en-us/library/ms143432.aspx ). 即使不这样做,SQL Server每个(非宽)表的限制为1024列,每行限制为8060字节( http://msdn.microsoft.com/en-us/library/ms143432.aspx )。 So, you can create a #Temp table in advance with maximum possible number of columns and use only some of them (make all your columns NULLable). 因此,您可以使用最大可能的列数预先创建#Temp表,并仅使用其中的一些(使所有列都为NULL)。

So, CREATE TABLE will look like this (instead of int use your type): 所以, CREATE TABLE看起来像这样(而不是int使用你的类型):

CREATE TABLE #Temp(c1 int NULL, c2 int NULL, c3 int NULL, ..., c1024 int NULL);

Yes, column names in #Temp will not be the same as in @Cols . 是的,#Temp中的列名与@Cols中的列名@Cols It should be OK for your processing. 你的处理应该没问题。

You have a list of columns in your @Cols variable. 您的@Cols变量中有列的列表。 You somehow make this list of columns in some external code, so when @Cols is generated you know how many columns there are. 你以某种方式在一些外部代码中创建了这个列列表,所以当生成@Cols时,你知道有多少列。 At this moment you should be able to generate a second list of columns that matches the definition of #Temp. 此时,您应该能够生成与#Temp定义匹配的第二列列。 Something like: 就像是:

@TempCols = N'c1, c2, c3, c4, c5';

The number of columns in @TempCols should be the same as the number of columns in @Cols . @TempCols的列@TempCols应与@Cols的列数相同。 Then your dynamic SQL would look like this (I have added INSERT INTO #Temp (@TempCols) in front of your code): 然后你的动态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 ;'

Then you execute your dynamic SQL: 然后执行动态SQL:

EXEC (@Sql) OR sp_executesql @Sql

And then do other processing using the #Temp table and temp column names c1, c2, c3, ... 然后使用#Temp表和临时列名称c1, c2, c3, ...进行其他处理

MSDN says : MSDN

A local temporary table created in a stored procedure is dropped automatically when the stored procedure is finished. 存储过程完成时,将自动删除在存储过程中创建的本地临时表。

You can also DROP the #Temp table explicitly, like this: 您也可以显式地DROP #Temp表,如下所示:

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

All this T-SQL code ( CREATE TABLE , EXEC , ...your custom processing..., DROP TABLE ) would naturally be inside the stored procedure. 所有这些T-SQL代码( CREATE TABLEEXEC ,...您的自定义处理..., DROP TABLE )自然会在存储过程中。

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 

Here is step by step solution for your problem. 这是您的问题的一步一步解决方案。

  1. Check for your temporary tables if they exist, and delete them. 检查临时表(如果存在),并将其删除。
 IF OBJECT_ID('tempdb..#temp') IS NOT NULL DROP TABLE #temp IF OBJECT_ID('tempdb..##abc') IS NOT NULL DROP TABLE ##abc 
  1. Store your main query result in first temp table (this step is for simplicity and more readability). 将主查询结果存储在第一个临时表中(此步骤是为了简化和提高可读性)。
 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. Write below query to create your pivot and store result in another temp table. 写下面的查询以创建您的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' 
  1. Execute below query to get the pivot result in your next temp table ##abc . 执行以下查询以在下一个temp table ##abc获取数据结果。

EXECUTE sp_executesql @sql

  1. And now you can use ##abc as table where-ever you want like 现在你可以使用##abc作为你想要的表

select * from ##abc

Hope this will help you. 希望这会帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM