I keep getting the “no data found” when I execute this PL/SQL block. If I comment out the output line, everything outputs as I would suspect, but the update statement never executes. Any ideas?
set serveroutput on;
Declare
TYPE type_emp IS RECORD(
emp_salary emp.salary%TYPE);
rec_emp type_emp;
v_stars varchar2(50) ;
v_count number(3);
s_num number(3);
begin
SELECT min(employee_id) into s_num from emp;
SELECT count(*) into v_count from emp;
v_count := v_count + s_num;
for i in s_num .. v_count loop
SELECT salary
into rec_emp
from emp
where employee_id = i;
if rec_emp.emp_salary <1000 then
v_stars := null;
elsif rec_emp.emp_salary >=1000 and rec_emp.emp_salary <2000 then
v_stars := '*';
elsif rec_emp.emp_salary >=2000 and rec_emp.emp_salary <3000 then
v_stars := '**';
elsif rec_emp.emp_salary >=3000 and rec_emp.emp_salary <4000 then
v_stars := '***';
elsif rec_emp.emp_salary >=4000 and rec_emp.emp_salary <5000 then
v_stars := '****';
elsif rec_emp.emp_salary >=5000 and rec_emp.emp_salary <6000 then
v_stars := '*****';
elsif rec_emp.emp_salary >=6000 and rec_emp.emp_salary <7000 then
v_stars := '******';
elsif rec_emp.emp_salary >=7000 and rec_emp.emp_salary <8000 then
v_stars := '*******';
elsif rec_emp.emp_salary >=8000 and rec_emp.emp_salary <9000 then
v_stars := '********';
elsif rec_emp.emp_salary >=9000 and rec_emp.emp_salary <10000 then
v_stars := '*********';
elsif rec_emp.emp_salary >=10000 and rec_emp.emp_salary <11000 then
v_stars := '**********';
elsif rec_emp.emp_salary >=11000 and rec_emp.emp_salary <12000 then
v_stars := '***********';
elsif rec_emp.emp_salary >=12000 then
v_stars := '************';
end if;
--dbms_output.put_line(rec_emp.emp_salary || ' ' || i || ' '|| v_stars);
update emp set emp.stars = v_stars where employee_id = i;
end loop;
end;
You’re using a very unusual method to iterate through all the records in the table. Your method assumes that the employee IDs are contiguous (i.e. no gaps). It also has an off-by-one error.
Let’s say your table has the following rows:
Firstly you get the minimum employee ID:
s_num = 100.Then, you get the count of records:
v_count = 5.Finally, you add these together to get the upper bound:
s_num + v_count = 105Can you see the problem with your loop now? On the last iteration, your query:
Will look for employee ID 105, which raises
NO_DATA_FOUND. The DBMS_OUTPUT calls were already done, so you’d see the output; but the unhandled exception causes a rollback, which means your UPDATEs are undone.Instead, you could make your loop much simpler, e.g.:
The above code is slightly more efficient too. It could be made even more efficient, but I don’t want this answer to go too far past what you’ve got so far.
I hope this helps.