游标内的存储过程不会从输出参数更新局部变量

时间:2018-01-22 16:09:40

标签: sql-server tsql stored-procedures cursors

我遇到了在游标的while循环中执行的存储过程的输出参数问题。

DECLARE @p_in int
DECLARE @p_out char

OPEN crs_clientId

FETCH NEXT FROM crs_clientId INTO @p_in

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @p_in

    EXEC dbo.usp_get_letter_for_number
             @in = @p_in, @out = @p_out OUTPUT;

    PRINT @p_out

    FETCH NEXT FROM crs_clientId INTO @p_in
END

CLOSE crs_clientId
DEALLOCATE crs_clientId

如果我独立运行此存储过程,我会得到:

1
A
2
B
3
C

但是,在游标中运行它我得到:

1
A
2
A
3
A

我错过了什么?为什么存储过程仅在第一次传递时更新@p_out

2 个答案:

答案 0 :(得分:1)

仍然不确定究竟是什么问题,但修复是在每次光标传递开始时将@p_out设置为null。出于某种原因,如果@p_out不为null,则存储过程的输出将不会写入它。

循环现在看起来像这样并且正常工作:

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @p_in
    SET @p_out = NULL;

    EXEC dbo.usp_get_letter_for_number
         @in = @p_in, @out = @p_out output

    PRINT @p_out

    FETCH NEXT FROM crs_clientId INTO @p_in
END

答案 1 :(得分:0)

我不确定你如何获得1,2,3,4的输出。因为代码似乎有问题。

您正在为游标分配一个值,这似乎是不正确的变量

请参阅@c_clientId

中的FETCH NEXT

所以也许你已经发布了一半代码。

或者你需要在游标循环结束时指定值来纠正可变量,即@p_in以获得正确的值

我尝试使用示例程序模拟返回值

--sample stored procedure
create procedure usp_get_letter_for_number(@in int, @out char(1) OUTPUT)
as
begin
    if @in = 1
        set @out = 'A'
    else if @in = 2
        set @out = 'B'
    else if @in = 3
        set @out =  'C'
    else 
        set @out = 'Z'
end

使用您的代码并将其更正为使用@pin代替@c_clientId并使用示例SELECT语句

DECLARE @p_in int
DECLARE @p_out char
DECLARE crs_clientId CURSOR FOR SELECT top 10 id from Users /*Sample sql query*/
OPEN crs_clientId

FETCH NEXT FROM crs_clientId INTO @p_in

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @p_in

    EXEC dbo.usp_get_letter_for_number
             @in = @p_in, @out = @p_out output

    PRINT @p_out

    FETCH NEXT FROM crs_clientId INTO @p_in
END

CLOSE crs_clientId
DEALLOCATE crs_clientId

输出

1
A
2
B
3
C
4
Z
5
Z
:
: