異常和游標管理
2024-07-21 02:40:47
供稿:網友
異常和游標治理 游標:用來查詢數據庫,獲取記錄集合(結果集)的指針,可以讓開發者一次訪問一行結果集,在每條結果集上作操作。 分類:靜態游標:分為顯式游標和隱式游標。REF游標: 是一種引用類型,類似于指針。 顯式游標: CURSOR 游標名 ( 參數 ) [返回值類型] IS Select 語句 生命周期:1. 打開游標(OPEN): 解析,綁定。。。不會從數據庫檢索數據2. 從游標中獲取記錄(FETCH INTO):執行查詢,返回結果集。通常定義局域變量作為從游標獲取數據的緩沖區。3. 關閉游標(CLOSE)完成游標處理,用戶不能從游標中獲取行。還可以重新打開。 選項:參數和返回類型 set serveroutput ondeclare cursor emp_cur ( p_deptid in number) is select * from employees where department_id = p_deptid; l_emp employees%rowtype;begin dbms_output.put_line(‘Getting employees from department 30’);open emp_cur(30); loop fetch emp_cur into l_emp; exit when emp_cur%notfound; dbms_output.put_line(‘Employee id ‘ l_emp.employee_id ‘ is ‘); dbms_output.put_line(l_emp.first_name ‘ ‘ l_emp.last_name); end loop; close emp_cur;
dbms_output.put_line(‘Getting employees from department 90’);open emp_cur(90); loop fetch emp_cur into l_emp; exit when emp_cur%notfound; dbms_output.put_line(‘Employee id ‘ l_emp.employee_id ‘ is ‘); dbms_output.put_line(l_emp.first_name ‘ ‘ l_emp.last_name); end loop; close emp_cur;end;/ 隱式游標:不用明確建立游標變量,分兩種:1. 在PL/SQL中使用DML語言,使用Oracle提供的名為SQL的隱示游標2. CURSOR FOR LOOP,用于for loop 語句。 1舉例:declarebegin update departments set department_name=department_name; --where 1=2; dbms_output.put_line(‘update ‘ sql%rowcount ’ records’);end;/
2舉例:declarebegin for my_dept_rec in ( select department_name, department_id from departments) loop dbms_output.put_line(my_dept_rec.department_id ‘ : ’ my_dept_rec.department_name); end loop;end;/ 游標屬性:%FOUND:變量最后從游標中獲取記錄的時候,在結果集中找到了記錄。%NOTFOUND:變量最后從游標中獲取記錄的時候,在結果集中沒有找到記錄。%ROWCOUNT:當前時刻已經從游標中獲取的記錄數量。%ISOPEN:是否打開。 Declare Cursor emps is Select * from employees where rownum<6 order by 1; Emp employees%rowtype; Row number :=1;Begin Open emps; Fetch emps into emp; Loop If emps%found then Dbms_output.put_line(‘Looping over record ‘row ‘ of ‘ emps%rowcount); Fetch emps into emp; Row := row + 1; Elsif emps%notfound then Exit; ---exit loop, not IF End if; End loop; If emps%isopen then Close emps; End if;End;/
顯式和隱式游標的區別:盡量使用隱式游標,避免編寫附加的游標控制代碼(聲明,打開,獲取,關閉),也不需要聲明變量來保存從游標中獲取的數據。 REF CURSOR游標:動態游標,在運行的時候才能確定游標使用的查詢。分類:強類型(限制)REF CURSOR,規定返回類型 弱類型(非限制)REF CURSOR,不規定返回類型,可以獲取任何結果集。 TYPE ref_cursor_name IS REF CURSOR [RETURN return_type] Declare Type refcur_t is ref cursor; Type emp_refcur_t is ref cursor return employee%rowtype;Begin Null;End;/ 強類型舉例:declare --聲明記錄類型 type emp_job_rec is record( employee_id number, employee_name varchar2(50), job_title varchar2(30) ); --聲明REF CURSOR,返回值為該記錄類型 type emp_job_refcur_type is ref cursor return emp_job_rec; --定義REF CURSOR游標的變量 emp_refcur emp_job_refcur_type;
emp_job emp_job_rec;begin open emp_refcur for select e.employee_id, e.first_name ‘ ’ e.last_name “employee_name”, j.job_title from employees e, jobs j where e.job_id = j.job_id and rownum < 11 order by 1; fetch emp_refcur into emp_job; while emp_refcur%found loop dbms_output.put_line(emp_job.employee_name ‘’’s job is ’); dbms_output.put_line(emp_job.job_title); fetch emp_refcur into emp_job; end loop;end;/ 單獨select declare l_empno emp.EMPLOYEE_ID%type;-- l_ename emp.ename%type;begin select EMPLOYEE_ID into l_empno from emp; --where rownum =1; dbms_output.put_line(l_empno);end;/使用INTO獲取值,只能返回一行。
錯誤處理:exception when <exception_eXPRession> then … when <exception_expression> then …end; exception_expression包括:1. 預定義表達式2. 用戶定義表達式3. PRAGMA EXCEPTION_INIT 預定義declare l_dept departments%rowtype;begin l_dept.department_id:=100; l_dept.department_name:=’HR’; insert into departments(department_id, department_name) values(l_dept.department_id, l_dept.department_name);Exception When DUP_VAL_ON_INDEX then Dbms_output.put_line(‘heihei’);end;/
DUP_VAL_ON_INDEX 異常 Exception When DUP_VAL_ON_INDEX then &nb