当游标的值为空的时候,处理无效员工的id时就会出现错误.
比如:
创建一个程序检索某个员工的工龄
a.创建一个函数GET_SERVICE_YRS,检索某个员工总的工龄;
此函数应该接受员工ID作为输入参数,返回工龄。增加例外处理无效的员工id输入;
b.调用函数,你能使用下面的数据
EXECUTE DBMS_OUTPUT.PUT_LINE(get_service_yrs(999))
表job_history为
create or replace function get_service_yrs(
p_employee_id in NUMBER)
return NUMBER
IS
service_year NUMBER(7,2) := 0;
sum_month NUMBER(7,2) := 0;
CURSOR cur_jobIS
SELECT start_date,end_date
FROM job_history
WHERE job_history.employee_id = p_employee_id;
e_invaild_1 EXCEPTION;
BEGIN
FOR job_his_recordIN cur_jobLOOP
sum_month := months_between(job_his_record.end_date,job_his_record.start_date);
sum_month := sum_month + sum_month;
IF SQL%NOTFOUND THEN
RAISE e_invaild_1;
END IF;
END LOOP;
service_year := (sum_month)/12;
return(service_year);
EXCEPTION
WHEN e_invaild_1THEN
dbms_output.put_line('无效的员工id');
RETURN NULL;
WHEN OTHERS THEN
dbms_output.put_line('............');
RETURN NULL;
end get_service_yrs;
---测试
DECLARE
BEGIN
dbms_output.put_line(get_service_yrs(999));
END;
当不存在该员工的ID时,就会出现意想不到的结果,比如下面,因为该游标为空,for循环根本进不去,在想想我们可以 不用游标,但游标有一个很大的功能就是取多值,而这个例子中就要多值,员工的总工龄,这时我们想到用loop,先进入循环在判断。
但要注意只用cur_job%notfound,就会出现游标不空时,也要调用异常,在加一个cur_job%count=0就解决问题了。
所以,
open cursor_name;
loop
fetch cursor_name into ....;
(加条件);
exit when ...;
end loop;
如下代码:
CREATE OR REPLACE FUNCTION GET_SERVICE_YRS(P_EMPLOYEE_ID IN NUMBER)
RETURN NUMBER IS
SERVICE_YEAR NUMBER(7, 2) := 0;
SUM_MONTH NUMBER(7, 2) := 0;
CURSOR CUR_JOB IS
SELECT START_DATE, END_DATE
FROM JOB_HISTORY
WHERE JOB_HISTORY.EMPLOYEE_ID = P_EMPLOYEE_ID;
E_INVAILD_1 EXCEPTION;
V_END_DATE JOB_HISTORY.END_DATE%TYPE;
V_START_DATE JOB_HISTORY.START_DATE%TYPE;
BEGIN
OPEN CUR_JOB;
LOOP
FETCH CUR_JOB
INTO V_START_DATE, V_END_DATE;
IF CUR_JOB%NOTFOUND AND cur_job%ROWCOUNT=0 THEN
RAISE E_INVAILD_1;
END IF;
EXIT WHEN CUR_JOB%NOTFOUND;
SUM_MONTH := SUM_MONTH + MONTHS_BETWEEN(V_END_DATE, V_START_DATE);
END LOOP;
CLOSE CUR_JOB;
SERVICE_YEAR := (SUM_MONTH) / 12;
RETURN(SERVICE_YEAR);
EXCEPTION
WHEN E_INVAILD_1 THEN
DBMS_OUTPUT.PUT_LINE('无效的员工id');
RETURN NULL;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RETURN NULL;
END GET_SERVICE_YRS;