存储过程内的游标未按预期工作

时间:2018-04-04 19:31:44

标签: sql-server tsql stored-procedures

我有一个sql存储过程,但是当我执行它时,它没有返回所需的输出。有人可以告诉我这里我做错了吗...

我在那里放了一些打印语句进行调试..问题似乎是游标没有获取任何结果。 @@ fetch_status的结果是-1

以下是我的存储过程:

ALTER PROCEDURE [dbo].[spComplaintsEmailAlert_autoFillForm] (@counterVal int,
@RESULT varchar(50) OUTPUT,
@RESULTDESC varchar(max) OUTPUT)
AS
  DECLARE @dateEmailSend varchar(50),
          @counter int,
          @region varchar(50),
          @ola_company varchar(50),
          @obj_identified_as varchar(50),
          @product_involved varchar(50),
          @ola_customer varchar(50),
          @product_ut varchar(50);

  DECLARE otherCounterVals CURSOR FOR
  SELECT
    A.CounterVal
  FROM [cmpEmailAlerted] A,
       [cmpTblProductComplaints] B
  WHERE A.CounterVal = B.Counter
  AND CONVERT(varchar(10), A.dateEmailSend, 120) = @dateEmailSend
  AND B.[Company] = @ola_company
  AND B.[Object Identified As] = @obj_identified_as
  AND B.[Product Involved] = @product_involved
  AND B.Region = @region
  AND B.[Customer] = @ola_customer
  AND A.CounterVal != @counter;

  DECLARE @aCounter int;

  BEGIN

    SELECT
      @dateEmailSend = CONVERT(varchar(10), A.dateEmailSend, 120),
      @counter = B.Counter,
      @region = B.Region,
      @ola_company = B.[Company],
      @obj_identified_as = B.[Object Identified As],
      @product_involved = B.[Product Involved],
      @ola_customer = B.[Customer],
      @product_ut = CONVERT(varchar(10), B.[produt u/t], 120)
    FROM [cmpEmailAlerted] A,
         [cmpTblProductComplaints] B
    WHERE A.CounterVal = @counterVal
    AND a.CounterVal = B.Counter;


    OPEN otherCounterVals;
    FETCH NEXT FROM otherCounterVals INTO @aCounter;
    PRINT @@fetch_status;

    PRINT 'start of the loop';
    WHILE @@FETCH_STATUS = 0

    BEGIN
      PRINT 'in the loop';
      SELECT
        @RESULTDESC = concat(@resultdesc, @aCounter, ',');

      FETCH NEXT FROM otherCounterVals INTO @aCounter;

    END;

    PRINT 'out the loop';

    CLOSE otherCounterVals;
    DEALLOCATE otherCounterVals;

    --remove the last comma from the resultdesc
    IF (SUBSTRING(@RESULTDESC, LEN(@RESULTDESC), 1) = ',')
    BEGIN
      SELECT
        @RESULTDESC = SUBSTRING(@RESULTDESC, 0, (LEN(@RESULTDESC)));
    END

    SELECT
      @RESULT = 'SUCCESS';

  END;

以下是我得到的输出:

  

-1循环开始循环

     

(受影响的一行)

     

(受影响的一行)

3 个答案:

答案 0 :(得分:2)

尚未为列出的第一个游标定义@值。

答案 1 :(得分:2)

如果您只想构建一个以逗号分隔的结果字符串,那么可以采用更简单的方法。一种不依赖任何神奇STUFF功能的直接,天真的方式就是这种模式:

DECLARE @result varchar(max);
SET @result = '';
SELECT @result = @result + ',' + ColumnValueToUse FROM MyTable WHERE <somecondition>
PRINT @result;

然后你可以剥掉第一个逗号。结果将是“MyTable”表中的“ColumValueToUse”的每个值,它满足条件......所有连接在一起并以逗号分隔。有更好的方法可以使用STUFF()和FOR XML来更好地处理逗号,并让你做更多花哨的东西。

使用昂贵的游标(甚至没有声明为FAST_FORWARD)是非常荒谬的。请不要。

至于光标解决方案无法正常工作的原因,请首先确保SELECT语句返回所需的行。鉴于您实际上没有在游标定义中设置SELECT使用的任何变量,它可能不会。但大多数情况下只需要移除光标。

试图从你自己的例子中推断出这样的事情:

DECLARE @result varchar(max);
SET @result = '';
SELECT @result = @result + ',' + A.CounterVal
  FROM [cmpEmailAlerted] A,
       [cmpTblProductComplaints] B
  WHERE A.CounterVal = B.Counter
  AND CONVERT(varchar(10), A.dateEmailSend, 120) = @dateEmailSend
  AND B.[Company] = @ola_company
  AND B.[Object Identified As] = @obj_identified_as
  AND B.[Product Involved] = @product_involved
  AND B.Region = @region
  AND B.[Customer] = @ola_customer
  AND A.CounterVal != @counter;
SELECT @result;

答案 2 :(得分:0)

您需要SELECT语句的每一行内部游标以及外部SELECT语句的外部游标。