如何将返回多个结果集的SQL存储过程中的单个结果集保存到临时表中?

如何将返回多个结果集的SQL存储过程中的单个结果集保存到临时表中?,sql,sql-server,tsql,sql-server-2000,temp-tables,Sql,Sql Server,Tsql,Sql Server 2000,Temp Tables,我需要将存储过程的结果集存储在临时表中(使用SQL Server) 2000). 从我所读到的内容来看,这个(构造欠佳的示例)应该可以: create table #tempTable (TempId int primary key, Column1 varchar(100), Column2 varchar(100), DateCreated datetime) insert into #tempTable (TempId, Column1, Column2, DateCreated) e

我需要将存储过程的结果集存储在临时表中(使用SQL Server) 2000). 从我所读到的内容来看,这个(构造欠佳的示例)应该可以:

create table #tempTable (TempId int primary key, Column1 varchar(100), 
Column2 varchar(100), DateCreated datetime)

insert into #tempTable (TempId, Column1, Column2, DateCreated)
exec sproc_Select_Stuff_By_DateCreated @Date1 = '1/1/2009', @Date2 = '1/2/2009'
但我得到: “插入错误:提供的值的列名或数目与表定义不匹配。”

检查过程(我无法编辑)会发现:

CREATE PROCEDURE sproc_Select_Stuff_By_DateCreated

@Date1 datetime,
@Date2 datetime
AS

BEGIN

SELECT TempId, Column1, Column2, DateCreated
FROM ReallyHugeMessOfJoinsAndCalculatedColumns
WHERE DateCreated between @Date1 and @Date2

SELECT @Date1 as Date1, @Date2 as Date2

END
所以它实际上是在回显作为第二个结果集传入的参数。(我不知道为什么;我想任何调用该过程的东西都会知道它传递了什么数据。)

我的测试让我认为第二个结果集是导致插入失败的原因——就像SQL试图将结果集合并在一起并失败一样

我只需要将第一个结果集保存到临时表中。我该怎么做

编辑

感谢您指出CLR存储过程,但该功能是在SQL 2005中引入的-它在2000年不起作用。(但我以前不知道它们,它们看起来在我们升级时会很有用。)


由于唯一的其他答案看起来是“你不能”——我想这对我来说又回到了绘图板上。

下面是一个完整的、有效的(SQL 2005)示例,说明了你所说的内容

坏消息是,我不相信有任何方法可以做你想做的事情。很抱歉看来是SP编写器让它变得不可能了

如果有人想出一些创造性的方法来让这项工作,太棒了

IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
    DROP TABLE #tempTable
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = 'sproc_Select_Stuff_By_DateCreated')
    DROP PROCEDURE dbo.sproc_Select_Stuff_By_DateCreated
GO
CREATE PROCEDURE dbo.sproc_Select_Stuff_By_DateCreated
    @Date1 datetime,
    @Date2 datetime
AS BEGIN
    ;WITH t AS (
        SELECT
            1                       AS TempId,
            'Column1-val1'          AS Column1,
            'Column2-val1'          AS Column2,
            '2009-01-01 10:00:00'   AS DateCreated
        UNION ALL
        SELECT
            2,
            'Column1-val2',
            'Column2-val2',
            '2009-01-01 11:00:00'
    )
    SELECT
        TempId,
        Column1,
        Column2,
        DateCreated
    FROM t -- ReallyHugeMessOfJoinsAndCalculatedColumns
    WHERE DateCreated between @Date1 and @Date2

    SELECT @Date1 as Date1, @Date2 as Date2
END
GO

create table #tempTable (
    TempId int primary key,
    Column1 varchar(100),
    Column2 varchar(100),
    DateCreated datetime
)

insert into #tempTable (TempId, Column1, Column2, DateCreated)
exec dbo.sproc_Select_Stuff_By_DateCreated
    @Date1 = '1/1/2009',
    @Date2 = '1/2/2009'

--SELECT * FROM #tempTable

----------------------------------------

Msg 213, Level 16, State 7, Procedure sproc_Select_Stuff_By_DateCreated, Line 26
Insert Error: Column name or number of supplied values does not match table definition.

通常,在普通SQL中,这是不可能的。Brannon的链接提供了使用CLR的可能解决方法


另一方面,如果可以选择重新分解,请考虑在第一个查询自己的存储过程中使其成为原子查询。然后可以从现有存储过程和任何其他代码中调用它。您的代码仍然只在一个地方,没有任何内容被破坏,您可以从纯SQL中获得更容易使用的内容。根据函数的不同,SP的第一部分甚至可能是内联表值函数的一个很好的候选者(我发现这些函数性能良好且灵活)。然后,您甚至不需要将输出捕获到一个临时表中,以便在执行其他处理时将其用作一个表(尽管您可能希望多次使用它)

由于无法更改存储过程,因此只有两个选项:

  • 使用CLR,它可以捕获两个结果集,并仅返回所需的结果集
  • 在自己的过程或视图中复制所需的查询。这是一个真正的黑客,CLR是首选。然而,你没有很多选择
来自


请参阅此相关问题:该问题有一个使用CLR的解决方法。您可以发布存储过程的一些结果吗?
INSERT EmployeeSales 
EXECUTE uspGetEmployeeSales;
GO