DBMS_OUTPUT не выбирает какие-либо строки в выводе, используя курсор - PullRequest
0 голосов
/ 25 апреля 2019

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 Ответ

1 голос
/ 25 апреля 2019

Причина, по которой ваш вывод не отображается, связана с 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;
/

N.B. Я удалил лишние BEGIN и END, которые были у вас внутри цикла; нет необходимости начинать новый блок внутри текущего!

Кроме того, я удалил вашу проверку, чтобы увидеть, открыт ли курсор или нет (он всегда будет закрыт в начале анонимного блока, поскольку курсор объявляется полностью в рамках анонимного блока, а Oracle закрывается Переменные после завершения области. Однако я добавил явный оператор 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 и вместо этого просто вывести результат.)

Приятной особенностью курсора для цикла является то, что вам не нужно объявлять переменные для возврата значений (запись неявно создается как часть оператора FOR <record> in (<cursor>)), и вам не нужно обрабатывать открытие и закрытие курсора. Это также делает ваш код намного проще и, следовательно, - IMO - легче для понимания и поддержки.

...