2

我需要将存储过程的结果集存储在临时表中(使用 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。(但我以前不知道它们,它们看起来在我们升级时会很有用。)

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

4

4 回答 4

2

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

  • 使用一个 CLR,它可以捕获两个结果集,并且只返回你想要的那个。
  • 在您自己的过程或视图中复制您需要的查询。这是一个真正的黑客,CLR 是首选。但是,您没有太多选择。
于 2009-10-08T17:43:33.057 回答
1

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

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

于 2009-10-08T16:37:31.770 回答
0

下面是一个完整的、工作的(对于 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.
于 2009-10-08T16:16:27.163 回答
-1

来自Microsoft T-SQL 参考

INSERT EmployeeSales 
EXECUTE uspGetEmployeeSales;
GO
于 2009-10-08T18:00:17.857 回答