DBMS_OUTPUT不使用游标获取输出中的任何行

时间:2019-04-25 07:10:11

标签: oracle plsql sqlplus

DBMS_OUTPUT.PUT_LINE在使用游标时没有返回数据,如以下代码所示

我使用布尔值比较表中的金额

SET SERVEROUTPUT ON; 
DECLARE
    --declaration of variable
     x_id        test.saa.id%TYPE;
     x_acctname   test.saa.acctname%TYPE;
     x_curbal      test.saa.balamt%TYPE;
     x_sid       test.saa.sid%TYPE;

--setting of the boolean value default to null
     b_lowamount   BOOLEAN := false;

    --declaration of cursor
    CURSOR custbal IS
    SELECT id,acctname,bal_amt,sid
    FROM
        test.saa WHERE ROWNUM <= 1000;
   BEGIN 
                  --checking cursor is open or not
                     IF NOT ( custbal%isopen ) THEN
                           OPEN custbal;
                      END IF; 
    LOOP
    FETCH custbal INTO
                  x_id,
                  x_acctname,
                  x_curbal,
                 x_sid;
EXIT WHEN custbal%notfound;
CONTINUE WHEN custbal%found;
--begin another 
BEGIN
    b_lowamount   := ( x_curbal < 10 );
    IF b_lowamount THEN
        dbms_output.put_line('The customer having '|| x_acctname|| ' with sol_id '|| x_sid|| 'with balance RS. '|| x_curbal);

    ELSE
        dbms_output.put_line('The customer having '|| x_acctname|| ' with sol_id '|| x_sid|| 'with balance RS. '|| x_curbal);
        END IF;
      END;
 END loop;
 end;

尽管过程成功完成,但未返回任何内容

1 个答案:

答案 0 :(得分:1)

之所以没有显示您的输出,是因为CONTINUE-这意味着转到下一个循环的开始。

相反,您的过程可以写为:

DECLARE
  --declaration of variable
  x_id       test.saa.id%TYPE;
  x_acctname test.saa.acctname%TYPE;
  x_curbal   test.saa.balamt%TYPE;
  x_sid      test.saa.sid%TYPE;

  --setting of the boolean value default to null
  b_lowamount BOOLEAN := FALSE;

  --declaration of cursor
  CURSOR custbal IS
    SELECT id,
           acctname,
           bal_amt,
           sid
    FROM   test.saa
    WHERE  rownum <= 1000;
BEGIN
  OPEN custbal;

  LOOP
    FETCH custbal
      INTO x_id,
           x_acctname,
           x_curbal,
           x_sid;
    EXIT WHEN custbal%NOTFOUND;

    b_lowamount := (x_curbal < 10);
    IF b_lowamount
    THEN
      dbms_output.put_line('The customer having ' || x_acctname || ' with sol_id ' || x_sid || 'with balance RS. ' || x_curbal);

    ELSE
      dbms_output.put_line('The customer having ' || x_acctname || ' with sol_id ' || x_sid || 'with balance RS. ' || x_curbal);
    END IF;
  END LOOP;

  CLOSE custbal;
END;
/

我删除了循环中多余的BEGINEND;无需在当前块内开始一个新块!

此外,我已经删除了检查游标是否打开的检查(由于匿名对象的游标完全在匿名块的范围内声明,因此它将始终在匿名块的开头关闭)一旦作用域结束,就添加变量,但是,我添加了一个明确的CLOSE语句来关闭游标。这并不是绝对必要的(因为一旦块完成,游标将自动关闭),但是如果您手动打开游标,请将其包括在内是一种很好的做法。

但是,您的整个过程可以简化为:

BEGIN
  FOR rec IN (SELECT id,
                     acctname,
                     bal_amt,
                     sid
              FROM   test.saa
              WHERE  rownum <= 1000)
  LOOP
    IF rec.bal_amt < 10
    THEN
      dbms_output.put_line('The customer having ' || rec.acctname || ' with sol_id ' || rec.sid || 'with balance RS. ' || rec.curbal);
    ELSE
      dbms_output.put_line('The customer having ' || rec.acctname || ' with sol_id ' || rec.sid || 'with balance RS. ' || rec.curbal);
    END IF;
  END LOOP;
END;
/

(即使两个分支都输出相同的字符串,我也照原样保留了IF语句-我认为这是一个错误,您的意思是要输出不同的文本,具体取决于余额是否少是否大于10?如果没关系,您可以删除IF语句,而只输出结果。)

关于cursor for循环的好处是,您无需声明变量即可将值返回(记录是作为FOR <record> in (<cursor>)语句的一部分隐式创建的),并且您不需要处理光标的打开和关闭。这也使您的代码更加简单,因此-IMO-更易于理解和维护。