Курсор для цикла, как напечатать сообщение, когда не найдено - PullRequest
0 голосов
/ 22 октября 2018

ОК, поэтому у меня есть курсор для цикла, который я хочу напечатать сообщение об ошибке, когда оператор выбора не находит курс, который вводил пользователь.Но проблема в том, что курсор для циклов автоматически завершается, когда оператор select не выполняется, поэтому мой оператор else никогда не выполняется.Как мне напечатать сообщение о том, что они, конечно, они ищут, не существует.Примечание переключение на выборку курсора не вариант.Например, если пользователь входит в существующий курс, он печатает всю необходимую информацию.Когда пользователь вводит курс без предварительных условий, он печатает правильное сообщение, но если пользователь вводит курс, который не существует, ничего не печатается.

DECLARE
course_name VARCHAR2(40) := '&course_input';
TYPE course_r IS RECORD(
  course_description course.description%TYPE,
  cost course.cost%TYPE,
  prerequisite course.prerequisite%TYPE,
  prerequisite_cost course.cost%TYPE
);
course_rec course_r;
CURSOR course_cursor IS
  SELECT a.description, a.cost, a.prerequisite,  b.cost AS preq_cost
  FROM COURSE a
  LEFT JOIN COURSE b ON a.prerequisite = b.course_no
  WHERE UPPER(a.description) LIKE '%'||'&course_input'||'%';

BEGIN
FOR record IN course_cursor
LOOP    
    course_rec.course_description := record.description;
    course_rec.cost := record.cost;
    course_rec.prerequisite := record.prerequisite;
    course_rec.prerequisite_cost := record.preq_cost;
IF course_rec.prerequisite IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('There is NO prerequisite course for any that starts on ' || course_name || '. Try again');
ELSIF course_rec.prerequisite IS NOT NULL THEN
    DBMS_OUTPUT.PUT_LINE('Course: ' || course_rec.course_description);
    DBMS_OUTPUT.PUT_LINE('Cost: ' || course_rec.cost);
    DBMS_OUTPUT.PUT_LINE('Prerequisite: ' || course_rec.prerequisite);
    DBMS_OUTPUT.PUT_LINE('Prerequisite Cost: ' || course_rec.prerequisite_cost);
    DBMS_OUTPUT.PUT_LINE('=================================================');
ELSE
    DBMS_OUTPUT.PUT_LINE('There is NO VALID course that starts on '||course_name||'. Try again.');
END IF;
END LOOP;
END;
/

Ответы [ 3 ]

0 голосов
/ 22 октября 2018

THE CURSOR FOR LOOP не выполняется, если в таблице курсов нет таких курсов. Итак, проверьте, существует ли строка перед входом в цикл.

Обратите внимание еще на две вещи:

  • LIKE '%'||'&course_input'||'%' не требуется в предложении where, так как эта же переменная уже передана из пользовательского ввода и назначена
    в разделе объявления. Просто используйте LIKE '%' || course_name || '%'

  • RECORD является зарезервированным словом PL / SQL и не должно использоваться как индексная переменная цикла
    , я изменил его на rec.


DECLARE
     course_name          VARCHAR2(40) := '&course_input';
     TYPE course_r IS RECORD ( course_description   course.description%TYPE,
     cost                 course.cost%TYPE,
     prerequisite         course.prerequisite%TYPE,
     prerequisite_cost    course.cost%TYPE );
     course_rec           course_r;
     cur_count            NUMBER;

     CURSOR course_cursor IS SELECT a.description,
                                    a.cost,
                                    a.prerequisite,
                                    b.cost AS preq_cost
                             FROM course a
                             LEFT JOIN course b ON a.prerequisite = b.course_no
                             WHERE upper(a.description) LIKE '%' || course_name || '%';
BEGIN
     SELECT COUNT(*)
      INTO cur_count
       FROM course a
     WHERE upper(a.description) LIKE '%' || course_name || '%';
     IF
          cur_count > 0
     THEN
          FOR rec IN course_cursor LOOP
               course_rec.course_description := rec.description;
               course_rec.cost := rec.cost;
               course_rec.prerequisite := rec.prerequisite;
               course_rec.prerequisite_cost := rec.preq_cost;
               IF
                    course_rec.prerequisite IS NULL
               THEN
                    dbms_output.put_line('There is NO prerequisite course for any that starts on ' ||
                    course_name || '. Try again');
               ELSE
                    dbms_output.put_line('Course: ' || course_rec.course_description);
                    dbms_output.put_line('Cost: ' || course_rec.cost);
                    dbms_output.put_line('Prerequisite: ' || course_rec.prerequisite);
                    dbms_output.put_line('Prerequisite Cost: ' || course_rec.prerequisite_cost);
                    dbms_output.put_line('=================================================');
               END IF;
          END LOOP;
     ELSE
          dbms_output.put_line('There is NO VALID course that starts on ' || course_name || '. Try again.'
          );
     END IF;
END;
/
0 голосов
/ 22 октября 2018

Вы можете сделать это, имея переменную, которая устанавливается только внутри цикла.Затем вы можете проверить эту переменную после завершения цикла, чтобы увидеть, была ли она установлена, и решить, нужно ли вам выполнять дополнительную работу.

Что-то вроде:

DECLARE
  course_name    VARCHAR2(40) := '&course_input';
  v_rows_present BOOLEAN := FALSE;
BEGIN
  FOR course_rec IN (SELECT a.description,
                            a.cost,
                            a.prerequisite,
                            b.cost AS preq_cost
                     FROM   course a
                     LEFT   JOIN course b
                     ON     a.prerequisite = b.course_no
                     WHERE  upper(a.description) LIKE '%' || course_name || '%')
  LOOP
    v_rows_present := TRUE;

    IF course_rec.prerequisite IS NULL
    THEN
      dbms_output.put_line('There is NO prerequisite course for any that starts on ' || course_name || '. Try again');
    ELSE
      dbms_output.put_line('Course: ' || course_rec.course_description);
      dbms_output.put_line('Cost: ' || course_rec.cost);
      dbms_output.put_line('Prerequisite: ' || course_rec.prerequisite);
      dbms_output.put_line('Prerequisite Cost: ' || course_rec.prerequisite_cost);
      dbms_output.put_line('=================================================');

    END IF;
  END LOOP;

  IF NOT v_rows_present
  THEN
    dbms_output.put_line('There is NO VALID course that starts on ' || course_name || '. Try again.');
  END IF;

END;
/

NB.обновил ваш код, поскольку вы, похоже, неправильно поняли, как использовать курсор для цикла.

  • Курсоры для циклов неявно создают свои собственные переменные записи, поэтому вам не нужно объявлять их самостоятельно.
  • Вам также не нужно явно указывать курсор - это можно сделать как часть оператора курсора для цикла.
  • Вам не нужно заполнять новую запись с помощьюте же значения из записи курсора для цикла, чтобы использовать значения (конечно, если вы используете их в цикле курсора!)
0 голосов
/ 22 октября 2018

Вы можете объявить счетчик, как, скажем, PLS_INTEGER, инициализировать его равным 0, а затем увеличить его внутри цикла.После цикла вы можете проверить значение, и если оно равно 0, вы знаете, что строки не были возвращены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...