plsql--游標用法


 1.游標概念

在 PL/SQL 塊中執行 SELECT、INSERT、DELETE 和 UPDATE 語句時,ORACLE 會在內存中為其分配上下文區(Context Area),即緩沖區。游標是指向該區的一個指針,或
是命名一個工作區(Work Area),或是一種結構化數據類型。它為應用等量齊觀提供了一種對具有多行數據查詢結果集中的每一行數據分別進行單獨處理的方法,是設計嵌入式
SQL 語句的應用程序的常用編程方式。


在每個用戶會話中,可以同時打開多個游標,其數量由數據庫初始化參數文件中的
OPEN_CURSORS 參數定義。
對於不同的 SQL 語句,游標的使用情況不同:
非查詢語句--》 隱式的
結果是單行的查詢語句 --》隱式的或顯示的
結果是多行的查詢語句--》 顯示的

2.處理顯示游標

2.1顯示游標處理的4個步驟

1.定義/ / 聲明 游標:就是定義一個游標名,以及與其相對應的 SELECT 語句。

格式:

CURSOR cursor_name[(parameter[, parameter]…)]
[RETURN datatype]
IS
select_statement;

注意:1.游標參數只能為輸入參數

2.在指定數據類型時,不能使用長度約束

3.[RETURN datatype]是可選的,表示游標返回數據的數據。如果選擇,則應該嚴格與 select_statement 中的選擇列表在次序和數據類型上匹配。一般是記錄數據類型或帶“%ROWTYPE”的數據。

2.打開游標

就是執行游標所對應的 SELECT 語句,將其查詢結果放入工作區,並且指
針指向工作區的首部,標識游標結果集合。如果游標查詢語句中帶有 FOR UPDATE 選
項,OPEN 語句還將鎖定數據庫表中游標結果集合對應的數據行。

格式:OPEN cursor_name[([parameter =>] value[, [parameter =>] value]…)];

3.提取游標

就是檢索結果集合中的數據行,放入指定的輸出變量中。

格式:FETCH cursor_name INTO {variable_list | record_variable };

執行 FETCH 語句時,每次返回一個數據行,然后自動將游標移動指向下一個數據行。當
檢索到最后一行數據時,如果再次執行 FETCH 語句,將操作失敗,並將游標屬性
%NOTFOUND 置為 TRUE。所以每次執行完 FETCH 語句后,檢查游標屬性%NOTFOUND
就可以判斷 FETCH 語句是否執行成功並返回一個數據行,以便確定是否給對應的變量賦了
值。

4.關閉游標

當提取和處理完游標結果集合數據后,應及時關閉游標,以釋放該游標所占
用的系統資源,並使該游標的工作區變成無效,不能再使用 FETCH 語句取其中數據。
關閉后的游標可以使用 OPEN 語句重新打開。


格式:CLOSE cursor_name;

注意:定義的游標不能有 INTO 子句。

 

游標屬性
游標屬性 屬性作用
Cursor_name%FOUND 布爾型屬性,當最近一次提取游標操作 FETCH成功則為 TRUE,否則為 FALSE;
Cursor_name%NOTFOUND 布爾型屬性,與%FOUND 相反;
Cursor_name%ISOPEN 布爾型屬性,當游標已打開時返回 TRUE;
Cursor_name%ROWCOUNT 數字型屬性,返回已從游標中讀取的記錄數。

 

2.2使用案例

--普通游標
declare
cursor emp_cursor1 is
select ename,sal from emp where sal < 1000;
v_name emp.ename%type;
v_sal emp.sal%type;
begin
open emp_cursor1;
loop
fetch emp_cursor1
into v_name,v_sal;
exit when emp_cursor1%notfound;
dbms_output.put_line(v_name || '---' || v_sal);
--dbms_output.put_line('isOpen:'||emp_cursor1%isopen); --查看游標狀態
end loop;
close emp_cursor1;
end;


--游標傳參
declare
cursor emp_cursor2(cursor_sal number default 2000) is --(此處的參數是默認參數,后面可以重新設置,此默認值失效)
select ename,sal from emp where sal >= cursor_sal;
v_name emp.ename%type;
v_sal emp.sal%type;
begin
open emp_cursor2(cursor_sal=>3000); --(重新設置參數值)
loop
fetch emp_cursor2
into v_name,v_sal;
exit when emp_cursor2%notfound;
dbms_output.put_line(v_name || '---' || v_sal);
end loop;
dbms_output.put_line('rowcount:'||emp_cursor2%rowcount); --(游標記錄數)
close emp_cursor2;
end;


--if...then(給工資低於2000的員工加薪1元)
declare
cursor emp_cursor3 is
select ename, sal, empno from emp;
v_no emp.empno%type;
v_name emp.ename%type;
v_sal emp.sal%type;
begin
open emp_cursor3;
loop
fetch emp_cursor3
into v_name, v_sal, v_no;
exit when emp_cursor3%notfound;
if v_sal <= 2000 then
update emp set sal = sal + 1 where empno = v_no;
dbms_output.put_line(v_name || '---' || v_sal);
end if;
end loop;
dbms_output.put_line('rowcount:' || emp_cursor3%rowcount);
close emp_cursor3;
end;


--有參數有返回值的游標(記錄類型)
declare
type emp_record_type is record(
v_no emp.empno%type,
v_name emp.ename%type,
v_sal emp.sal%type);
v_emp_record emp_record_type;
cursor emp_cursor4(dept_no number) return emp_record_type is
select empno, ename, sal from emp where deptno = dept_no;
begin
open emp_cursor4(dept_no=>20);
loop
fetch emp_cursor4
into v_emp_record;
if emp_cursor4%found then
dbms_output.put_line(v_emp_record.v_name || '---' ||
v_emp_record.v_sal);
else
dbms_output.put_line('已經處理完結果集');
exit;
end if;
end loop;
close emp_cursor4;
end;



--for循環格式游標
declare
cursor emp_cursor5 is
select ename, sal from emp;
begin
for v_sal in emp_cursor5 loop
dbms_output.put_line(v_sal.ename || '--***--' || v_sal.sal);
end loop;
end;

--for循環格式游標帶參數
declare
cursor emp_cursor5(dept_no number) is
select ename, sal from emp where deptno=dept_no;
begin
for v_sal in emp_cursor5(30) loop
dbms_output.put_line(v_sal.ename || '--***--' || v_sal.sal);
end loop;
end;


--for循環子查詢方式游標
begin
for v_sal in (select ename, sal from emp where deptno=20) loop
dbms_output.put_line(v_sal.ename || '--***--' || v_sal.sal);
end loop;
end;


3.處理隱式游標

 

顯式游標主要是用於對查詢語句的處理,尤其是在查詢結果為多條記錄的情況下;而對
於非查詢語句,如修改、刪除操作,則由 ORACLE 系統自動地為這些操作設置游標並創建
其工作區,這些由系統隱含創建的游標稱為隱式游標,隱式游標的名字為 SQL,這是由
ORACLE 系統定義的。對於隱式游標的操作,如定義、打開、取值及關閉操作,都由 ORACLE
系統自動地完成,無需用戶進行處理。用戶只能通過隱式游標的相關屬性,來完成相應的操
作。在隱式游標的工作區中,所存放的數據是與用戶自定義的顯示游標無關的、最新處理的
一條 SQL 語句所包含的數據。
格式調用為: SQL%

 

隱式游標屬性

屬性 值 SELECT INSERT UPDATE DELETE

SQL%ISOPEN FALSE FALSE FALSE FALSE

SQL%FOUND TRUE 有結果 成功 成功

SQL%FOUND FALSE 沒結果 失敗 失敗

SQL%NOTFUOND TRUE 沒結果 失敗 失敗

SQL%NOTFOUND FALSE 有結果 成功 失敗

SQL%ROWCOUNT 返回行數,只為 1插入的行數 修改的行數 刪除的行數

使用案例:

DECLARE
v_rows NUMBER;
BEGIN
--更新數據
UPDATE emp SET sal = 30000
WHERE deptno = 20;
--獲取默認游標的屬性值
v_rows := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('更新了'||v_rows||'個雇員的工資');
--回退更新,以便使數據庫的數據保持原樣
ROLLBACK;
END;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM