如何执行SELECT*INTO[temp table]FROM[存储过程]?不是FROM[Table]并且没有定义[temp Table]?

选择BusinessLine中的所有数据到tmpBusLine工作正常。

select *
into tmpBusLine
from BusinessLine

我也在尝试同样的方法,但使用返回数据的存储过程并不完全相同。

select *
into tmpBusLine
from
exec getBusinessLineHistory '16 Mar 2009'

输出消息:

消息156,级别15,状态1,第2行关键字附近的语法不正确“exec”。

我读过几个创建与输出存储过程结构相同的临时表的示例,这很好,但最好不要提供任何列。


当前回答

嗯,您确实需要创建一个临时表,但它不需要有正确的模式。。。。我创建了一个存储过程,它修改了现有的临时表,使其具有正确的数据类型和顺序(删除所有现有列,添加新列)所需的列:

GO
create procedure #TempTableForSP(@tableId int, @procedureId int)  
as   
begin  
    declare @tableName varchar(max) =  (select name  
                                        from tempdb.sys.tables 
                                        where object_id = @tableId
                                        );    
    declare @tsql nvarchar(max);    
    declare @tempId nvarchar(max) = newid();      
    set @tsql = '    
    declare @drop nvarchar(max) = (select  ''alter table tempdb.dbo.' + @tableName 
            +  ' drop column ''  + quotename(c.name) + '';''+ char(10)  
                                   from tempdb.sys.columns c   
                                   where c.object_id =  ' + 
                                         cast(@tableId as varchar(max)) + '  
                                   for xml path('''')  
                                  )    
    alter table tempdb.dbo.' + @tableName + ' add ' + QUOTENAME(@tempId) + ' int;
    exec sp_executeSQL @drop;    
    declare @add nvarchar(max) = (    
                                select ''alter table ' + @tableName 
                                      + ' add '' + name 
                                      + '' '' + system_type_name 
                           + case when d.is_nullable=1 then '' null '' else '''' end 
                                      + char(10)   
                              from sys.dm_exec_describe_first_result_set_for_object(' 
                               + cast(@procedureId as varchar(max)) + ', 0) d  
                                order by column_ordinal  
                                for xml path(''''))    

    execute sp_executeSQL  @add;    
    alter table '  + @tableName + ' drop column ' + quotename(@tempId) + '  ';      
    execute sp_executeSQL @tsql;  
end         
GO

create table #exampleTable (pk int);

declare @tableId int = object_Id('tempdb..#exampleTable')
declare @procedureId int = object_id('examplestoredProcedure')

exec #TempTableForSP @tableId, @procedureId;

insert into #exampleTable
exec examplestoredProcedure

请注意,如果sys.dm_exec_descript_first_result_set_for_object无法确定存储过程的结果(例如,如果它使用临时表),则这将不起作用。

其他回答

这是一个简单的2步过程:-创建临时表-插入临时表。

执行相同操作的代码:

CREATE TABLE #tempTable (Column1 int, Column2 varchar(max));
INSERT INTO #tempTable 
EXEC [app].[Sproc_name]
@param1 = 1,
@param2 =2;

我遇到了同样的问题,这是我根据保罗的建议所做的。这里的主要部分是使用NEWID()来避免多个用户同时运行存储过程/脚本,这是全局临时表的难题。

DECLARE @sql varchar(max) = '', 
@tmp_global_table varchar(255) = '##global_tmp_' + CONVERT(varchar(36), NEWID())
SET @sql = @sql + 'select * into [' + @tmp_global_table + '] from YOURTABLE'
EXEC(@sql)

EXEC('SELECT * FROM [' + @tmp_global_table + ']')

旧帖子但有用。除了其他答案,还可以将存储过程的输出捕获到表变量中(因为asker希望避免使用#temp表),因此我使用@table变量创建了一个完全有效的示例:

--Note: separately run each section at a time:
--Section-1: create stored proc that outputs a result-set:
    CREATE OR ALTER PROCEDURE TestSP AS
    BEGIN
        SELECT database_id, name from sys.databases
    END
------------------------
--Section-2: create @table-variable with columns matching the output (alternatively #Temp table can be used):
    DECLARE @t TABLE (did INT, dname VARCHAR(99))

    --Capture the output:
    insert into @t
    exec TestSP

    --View the captured output:
    select * from @t
------------------------
--Section-3: Clean-up
    DROP PROCEDURE TestSP

HTH.

最简单的解决方案:创建表#temp(…);插入#tempEXEC[sproc];

如果您不知道模式,那么可以执行以下操作。请注意,这种方法存在严重的安全风险。

SELECT * 
INTO #temp
FROM OPENROWSET('SQLNCLI', 
                'Server=localhost;Trusted_Connection=yes;', 
                'EXEC [db].[schema].[sproc]')

如果要在不首先声明临时表的情况下执行此操作,可以尝试创建用户定义函数而不是存储过程,并使该用户定义函数返回表。或者,如果要使用存储过程,请尝试以下操作:

CREATE TABLE #tmpBus
(
   COL1 INT,
   COL2 INT
)

INSERT INTO #tmpBus
Exec SpGetRecords 'Params'