oracle cursor 學習小結

一.概念:
遊標:用來查詢數據庫,獲取記錄集合(結果集)的指針,可以讓開發者一次訪問一行結果集,在每條結果集上作操作。
二.分類:
1.靜態遊標:
分爲顯式遊標和隱式遊標。
2 REF遊標:
是一種引用類型,類似於指針。
三.詳細內容:
1.顯式遊標:
CURSOR遊標名 (參數 ) [返回值類型 ] IS
  Select語句
生命週期:
a.打開遊標 (OPEN)
解析,綁定。。。不會從數據庫檢索數據
b.從遊標中獲取記錄 (FETCH INTO)
執行查詢,返回結果集。通常定義局域變量作爲從遊標獲取數據的緩衝區。
c.關閉遊標 (CLOSE)
完成遊標處理,用戶不能從遊標中獲取行。還可以重新打開。
選項:參數和返回類型
set serveroutput on
declare
 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;
/
 
2.隱式遊標:
不用明確建立遊標變量,分兩種:
a. PL/SQL中使用 DML語言,使用 ORACLE提供的名爲 SQL 的隱示遊標
b.CURSOR FOR LOOP,用於 for loop語句
a.舉例:
declare
begin
 update departments set department_name=department_name;
 --where 1=2;
 
 dbms_output.put_line('update '|| sql%rowcount ||' records');
end;
/

b.舉例:
declare
begin
 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;
/

c.舉例:
單獨 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獲取值,只能返回一行。
 
遊標屬性:
%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;
/
 
顯式和隱式遊標的區別:
儘量使用隱式遊標,避免編寫附加的遊標控制代碼(聲明,打開,獲取,關閉),也不需要聲明變量來保存從遊標中獲取的數據。
 
3 REF CURSOR遊標:
動態遊標,在運行的時候才能確定遊標使用的查詢。分類:
1.強類型(限制) REF CURSOR,規定返回類型
2.弱類型(非限制) 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;
/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章