Reputation: 801
In HR Schema
, I'm writing a PL/SQL block to fetch and display all employees having employee_id
from 150 to 200.
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;
However it works fine if there is data for all employee_id
from 150 to 200.
Suppose I am missing data for employee_id = 160
then this is the output.
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
How do I skip 160's error and display the other employees till employee_id = 200
?
When the select query fails, The execution of the loop must continue.
Note: I hopelessly tried to use a GOTO in EXCEPTION.
Upvotes: 0
Views: 1195
Reputation: 801
Implementation using 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;
Upvotes: 0
Reputation: 234
You can try like that
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;
Upvotes: 1
Reputation: 3303
Easiest way to do this is to use FOR loop with SELECT statement as shown below. Hope this helps.
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;
Upvotes: 1