PL / SQL无法为缺失值循环选择语句

时间:2017-03-02 07:04:18

标签: oracle for-loop select plsql

HR Schema中,我正在编写一个PL / SQL块来获取并显示从{150}到{200}的employee_id的所有员工。

declare
     v_c    number(3) := 150 ;
     v_fn   varchar2(150);
begin
     for i in  v_c .. v_c + 50
     loop
     select first_name into v_fn from employees where employee_id = i;
     dbms_output.put_line(i || ' ' || v_fn);
     end loop;    
end;

但是,如果所有employee_id的数据都在150到200之间,那么它可以正常工作。

假设我缺少employee_id = 160的数据,那么这就是输出。

Error report -
ORA-01403: no data found
ORA-06512: at line 7
01403. 00000 -  "no data found"
*Cause:    No data was found from the objects.
*Action:   There was no data from the objects which may be due to end of fetch.
150 Peter
151 David
152 Peter
153 Christopher
154 Nanette
155 Oliver
156 Janette
157 Patrick
158 Allan
159 Lindsey

如何跳过160的错误并将其他员工显示到employee_id = 200

当select查询失败时,必须继续执行循环。

注意:我绝望地尝试在EXCEPTION中使用GOTO。

3 个答案:

答案 0 :(得分:1)

最简单的方法是使用带有SELECT语句的FOR循环,如下所示。希望这会有所帮助。

BEGIN
  FOR i IN
  (SELECT employee_id,first_name FROM employees WHERE employee_id BETWEEN 150 AND 200
  )
  LOOP
    dbms_output.put_line(i.employee_id||' '||i.first_name);
  END LOOP;
END;

答案 1 :(得分:0)

你可以尝试那样

DECLARE
  v_c  NUMBER(3) := 150;
  v_fn VARCHAR2(150);
BEGIN
  FOR i IN v_c .. v_c + 50
  LOOP
    BEGIN
      SELECT first_name INTO v_fn FROM employees WHERE employee_id = i;
      dbms_output.put_line(i || ' ' || v_fn);
    EXCEPTION
    WHEN no_data_found THEN
      dbms_output.put_line('Employee not found, ID: ' || i);
      CONTINUE;
    END;
  END LOOP;
END;

答案 2 :(得分:0)

使用Cursors

实施
DECLARE
  c_id         employees.employee_id%type;
  c_first_name employees.first_name%type;
  v_end        NUMBER(3);
  CURSOR c_max_id
  IS
    SELECT MAX(employee_id) 
    FROM employees;
  CURSOR c_employees ( v_start NUMBER,v_end NUMBER )
  IS
    SELECT employee_id,first_name
    FROM employees
    WHERE employee_id BETWEEN v_start AND v_end;
BEGIN
  OPEN c_max_id;
  LOOP
    FETCH c_max_id INTO v_end;
    EXIT
  WHEN c_max_id%NOTFOUND;
    OPEN c_employees(150, v_end);
    LOOP
      FETCH c_employees INTO c_id, c_first_name;
      EXIT
    WHEN c_employees%notfound;
      dbms_output.put_line(c_id || ' ' || c_first_name);
    END LOOP;
    CLOSE c_employees;
  END LOOP;
  CLOSE c_max_id;
END;