遊標的屬性簡介:
遊標分爲顯示遊標和隱式遊標.
① %fFOUND 記錄獲取成功返回true,否則返回false
② %NOTFOUND 記錄獲取失敗返回true,否則返回false
③ %ROWCOUNT 返回已經從遊標中獲取的記錄數
④ %ISOPEN 如果遊標式打開的的,返回true,否則返回false(隱式遊標是oracle自動打開和關閉的,總是返回false)
⑤ %BULK_ROWCOUNT 返回FORALL語句更改的每個集合元素的記錄數
⑥ %BULK_EXCEPTION 返回FORALL更改的每個集合元素的記錄的異常信息
顯示遊標的4個步驟: 聲明 , 打開 , 提取記錄 , 關閉.
1) 聲明顯示遊標
CURSOR 遊標名 [(遊標參數列表)] [RETURN 返回值規範]
IS SELECT語句
[FOR UPDATE[OF [列名列表]]];
2) 打開顯示遊標
OPEN 顯示遊標名(參數列表);
3) 從顯示遊標中提取記錄
我們使用顯示遊標的目的就是爲了從遊標中返回或提取多行數據,然後操縱這些數據;
遊標實際就是PL/SQL中的一個虛表,我們需要從這個虛表中提取行,然後操縱行的信息
PL/SQl提供了FETCH語句執行該操作.
FETCH 遊標名 into 記錄或變量列表;
4) 關閉列表
CLOSE 遊標名;
例如:
declare
cursor cur_emp is select ename,sal from scott.emp; --定義遊標
row_emp cur_emp%rowtype; --基於遊標定義一個記錄
begin
open cur_emp; --打開遊標
fetch cur_emp into row_emp; --從遊標中提取一行添加到記錄中
while cur_emp%found --循環檢測遊標屬性,看是否到最後一行
loop
dbms_output.put_line(row_emp.ename||'--'||row_emp.sal);
fetch cur_emp into row_emp; --從遊標中提取一行添加到記錄中
end loop;
close cur_emp; --關閉遊標
end;
結果爲:
SMITH--800
ALLEN--1600
WARD--1250
JONES--2975
...
當我們提交一個select…for update語句時,Oracle自動對該select語句所影響的行用行級排他鎖鎖住,
CURSOR emp_cur IS
Select empno,ename,sal,from scott.emp where job=’manager’ from update;
CURSOR emp_cur IS
Select empno,ename,sal from scott.emp where job=’manager’ for update of sal;
我們還可以在for update後加nowait關鍵字,用於告訴oracle如果表已經被其他用戶鎖住,就不需要等待.
PL/SQL對於遊標使用過程的UPDATE和DELETE語句提供了WHERE CURRENT OF子句,使我們更容易的修改最近提取的數據行。
語法如下:
Update 表名 set set子句 where current of 遊標名;
Delete from 表名 where current of 遊標名.
例:
select * from scott.emp where job=('MANAGER')
declare
cursor emp_cur is
select empno,ename,sal from scott.emp where job='MANAGER' for update;
emp_row emp_cur%rowtype;
begin
open emp_cur;
loop
fetch emp_cur into emp_row;
if emp_cur%notfound --如果遊標中沒有記錄,或者到了最後一條記錄,就退出
then
exit;
else
update scott.emp set sal=sal+1000 where current of emp_cur; --修改當前記錄
end if;
end loop;
commit;
close emp_cur;
end;
遊標FOR循環:
FOR 記錄 IN 遊標名
LOOP
執行語句
END LOOP;
這裏的記錄不需要我們顯式定義的,它根據指定的遊標名,用%rowtype屬性隱式的定義的,注意,遊標FOR循環僅用在處理遊標中的每一條記錄時.
declare
cursor emp_cur is
select empno,ename,sal from scott.emp where job='MANAGER' for update;
begin
for emp_row in emp_cur
Loop
update scott.emp set sal=sal-1000 where current of emp_cur;
end loop;
commit;
end;
與上比較
*BULK COLLECT
在Oracle 8i以前,要返回多行數據只能使用顯式遊標.在Oracle 8i中引入了bulk collect子句,可以用對數據庫的一個來回,返回多行數據.
… BULK COLLECT INTO 集合名[,集合名]…
規則:
在oracle 9i前,我們只能在靜態SQL中使用bulk collect.在oracle9i以後,在靜態和動態SQL中都可以使用該子句.
可以在SELECT INTO,FETCH INTO,RETURNING INTO 子句中使用
BULK COLLECT輸出到的集合只能存儲標量值(字符串,數字,日期等).換句話說,不能把一行數據提取到集合中的一個記錄結構的行中.
SQL引擎自動初始化和擴展在BULK COLLECT 子句中引用的集合,它從集合的索引1開始填充,連續的插入元素,並把以前定義的任何元素值覆蓋.
不能在FORALL語句中使用select …bulk collect語句.
如果沒有查詢到行,select..bulk collect 不能拋出NO_DATA_FOUND異常.因此,必須檢查集合的內容,看是否有數據
在執行查詢之前,bulk collect操作將會清空into子句引用的集合的內容.如果查詢沒有返回行,那麼集合的count方法會返回0.
現在我們用select..bulk collect into 改寫上面的顯式遊標示例
代碼如下:
declare
type emp_table_type is table of scott.emp%rowtype index by binary_integer;
emp_table emp_table_type;
begin
select * bulk collect into emp_table from scott.emp;
for i in 1..emp_table.count
loop
dbms_output.put_line(emp_table(i).empno||'--'||emp_table(i).ename);
end loop;
end;
也可以用fetch…into應用bulk collect子句
declare
cursor cur_emp is select * from scott.emp;
type row_emp_type is table of cur_emp%rowtype index by binary_integer;
row_emp row_emp_type;
begin
open cur_emp;
fetch cur_emp bulk collect into row_emp;
for i in 1..row_emp.count
loop
dbms_output.put_line(row_emp(i).empno||'--'||row_emp(i).ename);
end loop;
close cur_emp;
end;
結果如下
7369--SMITH
7499--ALLEN
7521--WARD
7566--JONES
7654--MARTIN
7698--BLAKE
7782--CLARK
7788--SCOTT
7839--KING
7844--TURNER
7876--ADAMS
7900--JAMES
7902--FORD
7934—MILLER
*遊標變量和REF CURSOR
遊標變量是一個指向或者引用下層遊標的變量.顯式遊標是對PL/SQL 結果集工作區命名,而遊標變量則是對該工作區的一個引用,顯式遊標和隱式遊標要綁定到特定的查詢,因而是靜態的.而遊標變量可以爲任何查詢打開,甚至在單個程序執行期間可以爲不同的查詢打開.,遊標可以在訪問遊標變量的程序之間共享.
---使用和顯式遊標基本類似;
定義REF CURSOR類型的遊標變量
語法如下:
Return子句是可選的
TYPE cursor_type_name IS REF CURSOR[RETURN return_type];
引用遊標名稱 return數據規範
弱類型的遊標變量:沒有將遊標類型與記錄數據結構相關聯,比強類型的遊標變量更有靈活性,
從oracle9i數據開始,oracle提供了一種名爲SYS_REFCURSOR的預定義的REF CURSOR,
我們可以直接按照如下方法使用,而不需要定義自己的弱類型遊標變量:
DECLARE
my_cursor SYS_REFCURSOR;
定義一個遊標變量語法如下:
Cursor_name cursor_type_name;
示例:
Declare
/* 爲僱員創建一個遊標類型*/
TYPE emp_cur_type IS REF CURSOR RETURN emp%ROWTYPE;
/*爲僱員創建一個遊標變量.*/
emp_cur emp_cur_type;
BEGIN
…
END;
PL/SQL遊標
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.