Cursor For Loop找不到时如何打印消息

时间:2018-10-21 21:27:28

标签: oracle plsql

好,所以我有一个循环游标,当select语句找不到用户输入的课程时,我想打印一条错误消息。但是问题是,当select语句失败时,cursor for循环会自动退出,因此我的else语句永远不会执行。我如何打印一条消息说他们正在寻找的课程不存在。注意,切换到游标提取不是一个选择。例如,id用户进入的课程已经存在,它将打印所有相关信息。当用户输入没有任何先决条件的课程时,它会打印一条正确的消息,但是,如果用户输入的课程不存在,则不会打印任何内容。

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 :(得分:2)

您可以声明一个计数器,例如PLS_INTEGER,将其初始化为0,然后在循环内递增。循环后,您可以检查该值,如果该值为0,则表示没有返回任何行。

答案 1 :(得分:1)

如果课程表中没有这样的课程,则CURSOR FOR LOOP不会执行。因此,在进入循环之前,请检查是否存在一行。

另外两件事要注意:

    where子句中不需要
  • LIKE '%'||'&course_input'||'%' 因为已经从用户输入传递并分配了相同的变量
    在声明部分。只需使用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;
/

答案 2 :(得分:1)

您可以通过只在循环内设置变量来实现。然后,您可以在循环完成后检查该变量,以查看是否已设置该变量,并确定是否需要做其他工作。

类似的东西:

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;
/

由于您似乎误解了如何使用游标进行循环,因此我已经更新了您的代码。

  • 游标循环可隐式创建自己的记录变量,因此您无需自己声明一个变量。
  • 您也不需要显式声明游标-可以将其作为cursor-for-loop语句的一部分来完成。
  • 使用循环游标记录中的相同值填充新记录即可使用这些值(当然,只要您在循环游标中使用它们,就可以了) !)