如何执行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”。

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


当前回答

如果OPENROWSET给您带来问题,从2012年起还有另一种方法;使用sys.dm_exec_descript_first_result_set_for_object,如下所述:检索存储过程的列名和类型?

首先,创建此存储过程以生成临时表的SQL:

CREATE PROCEDURE dbo.usp_GetStoredProcTableDefinition(
    @ProcedureName  nvarchar(128),
    @TableName      nvarchar(128),
    @SQL            nvarchar(max) OUTPUT
)
AS
SET @SQL = 'CREATE TABLE ' + @tableName + ' ('

SELECT @SQL = @SQL + '['+name +'] '+ system_type_name +''  + ','
        FROM sys.dm_exec_describe_first_result_set_for_object
        (
          OBJECT_ID(@ProcedureName), 
          NULL
        );

--Remove trailing comma
SET @SQL = SUBSTRING(@SQL,0,LEN(@SQL))    
SET @SQL =  @SQL +')'

要使用该过程,请按以下方式调用它:

DECLARE     @SQL    NVARCHAR(MAX)

exec dbo.usp_GetStoredProcTableDefinition
    @ProcedureName='dbo.usp_YourProcedure',
    @TableName='##YourGlobalTempTable',@SQL = @SQL OUTPUT

INSERT INTO ##YourGlobalTempTable
EXEC    [dbo].usp_YourProcedure

select * from ##YourGlobalTempTable

注意,我使用的是全局临时表。这是因为使用EXEC运行动态SQL会创建自己的会话,因此普通临时表将超出任何后续代码的范围。如果全局临时表有问题,可以使用普通临时表,但任何后续SQL都需要是动态的,也就是说,也可以由EXEC语句执行。

其他回答

您可以为此使用OPENROWSET。看一看我还包含了sp_configure代码,以启用特殊分布式查询(如果尚未启用)。

CREATE PROC getBusinessLineHistory
AS
BEGIN
    SELECT * FROM sys.databases
END
GO

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

SELECT * INTO #MyTempTable FROM OPENROWSET('SQLNCLI', 'Server=(local)\SQL2008;Trusted_Connection=yes;',
     'EXEC getBusinessLineHistory')

SELECT * FROM #MyTempTable

我发现将数组/数据表传递到存储过程中,这可能会让您对如何解决问题有另一个想法。

该链接建议使用Image类型参数传递到存储过程中。然后在存储过程中,图像被转换为包含原始数据的表变量。

也许有一种方法可以用于临时表。

这可以在SQL Server 2014+中完成,前提是存储过程只返回一个表。如果有人能为多张桌子找到这样的方法,我很想知道。

DECLARE @storedProcname NVARCHAR(MAX) = ''
SET @storedProcname = 'myStoredProc'

DECLARE @strSQL AS VARCHAR(MAX) = 'CREATE TABLE myTableName '

SELECT @strSQL = @strSQL+STUFF((
SELECT ',' +name+' ' + system_type_name 
FROM sys.dm_exec_describe_first_result_set_for_object (OBJECT_ID(@storedProcname),0)
FOR XML PATH('')
),1,1,'(') + ')'

EXEC (@strSQL)

INSERT INTO myTableName

EXEC ('myStoredProc @param1=1, @param2=2')

SELECT * FROM myTableName

DROP TABLE myTableName

这将从系统表中提取返回表的定义,并使用它为您构建临时表。然后,您可以如前所述从存储过程填充它。

还有一些变体也适用于动态SQL。

我正在使用以下模式和数据创建一个表。创建存储过程。现在我知道我的过程的结果是什么,所以我正在执行以下查询。创建表[dbo]。[tbl测试树]([Id][int]标识(1,1)不为空,[ParentId][int]NULL,[IsLeft][bit]NULL,[IsRight][bit]NULL,CONSTRAINT[PK_tblTestingTree]主键集群([Id]ASC)(PAD_INDEX=关闭,STATISTICS_NORECOMPUTE=关闭,IGNORE_DUP_KEY=关闭,ALLOW_ROW_LOCKS=打开,ALLOW_PAGE_LOCKS=开启)打开[主])在[主要]去设置IDENTITY_INSERT[dbo]。[tbl测试树]打开插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(1,NULL,NULL,空)插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(2,1,1,NULL)插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(3,1,NULL,1)插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(4,2,1,NULL)插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(5,2,NULL,1)插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(6,3,1,NULL)插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(7,3,NULL,1)插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(8,4,1,NULL)插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(9,4,NULL,1)插入[dbo]。[tblTestingTree]([Id],[ParentId],[IsLeft],[IsRight])值(10,5,1,NULL)设置IDENTITY_INSERT[dbo]。[tbl测试树]关闭值(10,5,1,NULL)设置IDENTITY_INSERT[dbo]。[tblTestingTree]打开创建过程GetDate像开始从tblTestingTree中选择Id、ParentId终止创建表tbltemp(id int,父ID int)插入tbltempexec获取日期从tbltemp中选择*;

旧帖子但有用。除了其他答案,还可以将存储过程的输出捕获到表变量中(因为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.