调用存储过程从存储过程中返回记录集

时间:2010-09-16 11:34:58

标签: sql-server stored-procedures

在SQL Server 2005中工作,我有一个存储过程,插入记录并通过SELECT @@ IDENTITY返回新的ID;作为最后一个命令。

然后我想从另一个存储过程中调用它,并获取新ID的值。

但我无法弄清楚如何从第一个程序中获取返回的值。

示例:

CREATE PROCEDURE spMyInsert(@Field1 VARCHAR(10)) AS 
BEGIN

    INSERT INTO tMyTable (Column1) VALUES (@Field1); // ID column implicitly set

    SELECT @@IDENTITY ID;

END


CREATE PROCEDURE spMyMain AS
BEGIN

    DECLARE @NewID INT;

    EXEC spMyInsert 'TEST';

    // How do I set @NewID to the value returned from spMyInsert?

END

还有另一个question几乎回答了我的问题,但并不完全。这解释了如何将结果插入到另一个表中,但我想要做的就是将其存储在局部变量中。

看看其他类似的问题,一般的答案是更改为设置OUTPUT变量或创建一个函数来执行此操作,但我无法在我的情况下执行此操作,因为其他.NET数据访问内容使用相同的存储proc,我也不想将存储过程的所有工作都复制为函数。

我尝试了几件但都失败的事情是:

SET @NewID = (EXEC spMyInsert 'TEST');

SET @NewID = (SELECT ID FROM (EXEC spMyInsert 'TEST'));

有人知道怎么做吗?

谢谢, 本

5 个答案:

答案 0 :(得分:4)

顺便说一下,您应该检查@@identity是否是您所需要的而不是scope_identity

如果 你需要什么,那么它仍然可以在调用存储过程中访问。

CREATE PROCEDURE spMyMain 
AS
BEGIN
    DECLARE @NewID INT;

    EXEC spMyInsert 'TEST';

    SET @NewID = @@IDENTITY

    SELECT @NewID AS '@NewID'

END

如果使用scope_identity并且不想使用输出参数或过程返回代码,则需要应用的更通用的解决方案是

CREATE PROCEDURE spMyMain AS
BEGIN

 DECLARE @NewID INT;

    DECLARE @IdHolder TABLE
    (
    id INT
    )

    INSERT INTO @IdHolder
    EXEC spMyInsert 'TEST';

    IF @@ROWCOUNT<>1
    RAISERROR('Blah',16,1)

     SELECT @NewID = id FROM @IdHolder

END

答案 1 :(得分:2)

首先,不要使用@@ IDENTITY,而是使用SCOPE_IDENTITY()(搜索此网站或Google的原因)。然后只返回输出参数中的值:

CREATE PROCEDURE spMyInsert(@Field1 VARCHAR(10), @NewID int output) AS  
BEGIN 
    INSERT INTO tMyTable (Column1) VALUES (@Field1);
    SET @NewID = scope_identity();
END 
 go

CREATE PROCEDURE spMyMain AS 
BEGIN 
     DECLARE @NewID INT; 
     EXEC spMyInsert @Field1 = 'TEST', @NewID = @NewID OUTPUT; 
END
go

答案 2 :(得分:2)

这里的问题是spMyInsert会返回一个Select。当您执行spMyMain时,它将返回spMyInsert中的选择,然后从spMyMain中选择

我建议您修改spMyInsert以使用OUTPUT参数

CREATE PROCEDURE spMyInsert(@Field1 VARCHAR(10), @NewId int output) AS 
BEGIN

    INSERT INTO tMyTable (Column1) VALUES (@Field1); // ID column implicitly set

    SELECT @NewId = @@SCOPE_IDENTITY;

END

然后

CREATE PROCEDURE spMyMain AS
BEGIN

    DECLARE @NewID INT;
Set @NewId = 0

    EXEC spMyInsert 'TEST', @NewId output;

select @NewId
    // How do I set @NewID to the value returned from spMyInsert?

END

请注意,我还将@@Identity更改为@@scope_identity最好使用@@Scope_Identity,因为这会返回适用于当前连接的新ID。

答案 3 :(得分:1)

试试这个:

Execute @NewID = spMyInsert 'TEST'

编辑:更彻底地阅读他的问题并意识到他正在处理一个选择而不是一个返回:你可以在函数调用中包装该过程然后调用该函数吗?

select @NewId = from fnMyInsert('TEST')

答案 4 :(得分:1)

输出参数是要走的路,但是如果你真的无法改变内部SP,那么就像你说的那样,你可以让内部SP将其结果返回到表中,然后从中获取值。

例如

declare @NewID int,
@Customer table(CustomerId int);

insert into @Customer
exec spMyInsert 'TEST';

select @NewID = CustomerId from @Customer;