如何在另一个存储过程中使用一个存储过程的值?

21

我在一个存储过程中有以下语句:

DECLARE @Count INT
EXEC @Count = GetItemCount 123
SELECT @Count

该存储过程调用另一个带有以下语句的存储过程:

SELECT COUNT(Item) 
FROM tblItem 
WHERE ID = @ID

然而,当我测试调用EXEC时,它输出了正确的值,但是没有正确地分配给@Count参数。

我看到过像这样使用存储过程的示例,包括这里,但没有一个参数和返回值被使用(至少我没找到)。

ID参数被传递到第二个语句中,该语句返回一个计数值,由第一个存储过程使用——我读到的所有信息似乎表明这应该可以工作——但它不起作用,即使GetItemCount总是返回正确的值,@Count的值始终为零。

如果有帮助的话,这是在Microsoft SQL Server 2008中。


我成功地让它工作了 - 将输出作为参数是解决方案 - 我总是忘记 SQL 不像我习惯的编程风格。 - RoguePlanetoid
8个回答

41
在你的存储过程中,你是否要么
a) 将计数值分配给一个输出参数:
CREATE PROCEDURE GetItemCount
  @id INT,
  @count INT OUTPUT
AS
  SELECT @count = COUNT(Item) FROM tblItem WHERE ID = @id

调用方式:

DECLARE @count INT
EXEC GetItemCount 123, @count OUTPUT

或者,b) 将计数值分配为返回值:

CREATE PROCEDURE GetItemCount
  @id INT
AS
BEGIN
  DECLARE @count INT
  SELECT @count = COUNT(Item) FROM tblItem WHERE ID = @id

  RETURN @count
END  

被称为:

DECLARE @count INT
EXEC @count = GetItemCount 123

谢谢,这个可行 - 我没有想到输出会是一个参数 - 这就是我无法理解的原因。我把显示输出当作输出来处理,而实际上没有返回任何东西 - 这就是为什么我读取值时它是零的原因。 - RoguePlanetoid
自从我提出这个问题并回到这里找到解决方案后,我已经多次搜索了这个问题,并希望每次它帮助了我都能点赞! - RoguePlanetoid

10

另一种方法

DECLARE @Count table(counting INT)
Insert into @Count
EXEC GetItemCount 123 
SELECT Counting FROM @Count 

@MortezaFarhadi 它在2008年也可以工作。你有收到任何错误吗? - Madhivanan

3
如果执行的存储过程没有输入参数,则以下操作将无法进行:
EXEC [dbo].insertproduc 'TEST', @ProductID OUTPUT --works
EXEC [dbo].insertproduc, @ProductID OUTPUT -- generates a parameter supplied when not needed error message if the insertproduc does not require parameters.

对于所有情况,最好使用以下格式(在所有版本中都有效):

DECLARE @MyOutputVariable int 
EXEC @MyOutputVariable  = [dbo].MyStoredProc 

2

你应该将@Count作为输出参数传递。

Create Proc dbo.usp_Proc1

@Id int,
@Count int output

as begin

select @Count = Count(Item) from tblItem where id=@Id

end
Go

Declare @Count int
Declare @Id int

Set @Id = 1

Exec dbo.usp_Proc1 @Id, @Count output

select @Count

这个例子对我正确运行查询也很有帮助,再次感谢。 - RoguePlanetoid

1
问题描述:在另一个存储过程中调用Matthew先生提供的解决方案(b)时,此解决方案将不起作用。(当然,如果我们使用OUTPUT参数,则解决方案(a)完美地工作)。Madhivanan先生提供了一个替代解决方案(b),即创建一个临时表,使用它,然后删除它。

其他解决方案如下:

我们无法直接从存储过程的内部OUTPUT子句中获取值。因此,我们必须使用OUTPUT参数或RETURN VALUE。

解决方案1:

CREATE PROCEDURE [dbo].[InsertProduct] 
      @pName varchar(50) 
AS 


BEGIN 
DECLARE @MyTableVar Table(ProductID 
int) 


      INSERT Products 
      ( 
           pName 
      ) 
      OUTPUT Inserted.ProductID 
INTO @MyTableVar 
      VALUES 
      ( 
        @pName 
      ) 
RETURN (SELECT ProductID
FROM @MyTableVar) 
END 


DECLARE @ProductID int 
EXEC @ProductID = [dbo].insertproduc 'TEST' 
SELECT @ProductID 

解决方案:2

CREATE PROCEDURE [dbo].[InsertProduct]
      @pName varchar(50) , @pID int output
AS

BEGIN 
DECLARE @MyTableVar Table(ProductID int)

      INSERT Products 
      (
           pName 
      )
      OUTPUT Inserted.ProductID INTO @MyTableVar
      VALUES 
      (
        @pName
      )
SELECT @pID=ProductID FROM @MyTableVar
END

DECLARE @ProductID int
EXEC [dbo].insertproduc 'TEST', @ProductID OUTPUT
SELECT @ProductID

0

你在变量@Count中捕获的是存储过程GetItemCount的执行状态,而不是你期望的值。要捕获该值,有两种方法。

  1. GetItemCount 中声明另一个参数 @countOUTPUT。因此,您将拥有以下 GetItemCount 声明:

     CREATE PROCEDURE GetItemCount @ID int, @count int OUTPUT
    

    在内部,您可以使用以下代码:

     SELECT @count = COUNT(Item) 
     FROM tblItem 
     WHERE ID = @ID
    
  2. 在调用过程并将该值作为列获取之前,先声明一个表。


0

你也可以尝试基于Madhivanan的答案:

DECLARE @tblItem table(Item INT)
DECLARE @Count INT

Insert into @tblItem 
EXEC GetItemCount 123 
SELECT @Count = Item FROM @tblItem 

0

在阅读所有答案后,简化它。使用了两个输入和两个输出参数。

确保在存储过程中为输出参数分配一些值。

我的存储过程:

CREATE PROCEDURE [dbo].[MyStoredProcedure]
    (@InParam1  VARCHAR(20) = NULL,
     @InParam2  VARCHAR(20) = '',
     @OutParam1 VARCHAR(20) = NULL OUT,
     @OutParam2 VARCHAR(20) = NULL OUT)
AS
BEGIN
    SET @OutParam1 = 'Whatever you want to return'
    SET @OutParam2 = 'Whatever you want to return'
    RETURN 0; --This is final value any SP returns by default 0
END

调用这个存储过程 - 我使用了两个输出参数,所以我们需要在执行存储过程之前声明它们:

DECLARE @OutParam1 VARCHAR(20)
DECLARE @OutParam2 VARCHAR(20)

即使您最终不需要存储过程中的任何变量(例如@Var),也可以使用它,但这将设置输出参数而不返回任何数据,就像它返回一样:

方法1:

DECLARE @Var INT
EXEC @Var = MyStoredProcedure 'InParam1', 'InParam2', @OutParam1 OUT, @OutParam2 OUT

如果你想从你的存储过程中返回一些选择语句,并且想要使用这些值,你可以将它们保存在一个临时表中,或者直接作为一个选择查询。

方法二:

插入到一个临时表中。

@DECLARE @TableTemp TABLE
                    (
                        Column1 VARCHAR(20),
                        Column2 VARCHAR(20)
                    )

INSERT INTO @TableTemp
    EXEC MyStoredProcedure 'InParam1', 'InParam2', @returnParam1 OUT, @returnParam2 OUT

这将设置两个输出参数从MyStoredProcedure,并插入您从MyStoredProcedure传递的值作为选择语句。

方法3:

要仅将返回的值用作表数据,我们可以使用以下方法:

EXEC MyStoredProcedure 'InParam1', 'Inparam2', @returnParam1 OUT, @returnParam2 OUT

在以上所有情况下,输出参数始终被设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接