顯示游標獲取資料 PL SQL

2021-06-22 08:36:58 字數 4666 閱讀 7638

--在oracle中,當我們從pl/sql中執行一條select語句時,oracle rdbms(關聯式資料庫管理系統)會為該語句在sga的共享池中分配乙個私有sql區,

--同時在將查詢結果集放入系統全域性區sga中,以提高訪問和修改結果集的效能。

--私有sql區包含了該語句的資訊以及結果集的資訊。oracle中使用游標作為指標來引用該私有工作區。

--借助游標,pl/sql程式可以控制私有工作區和語句處理過程中游標的變化。

--pl/sql中的游標分為隱示游標(執行乙個返回單行的select into 時,oracle自動處理相關操作)

--和顯示游標(手動處理相關操作,獲取多行,重用性強)兩種型別。

--乙個典型的查詢操作步驟如下:

--解析:確保sql語句有效,然後決定執行計畫

--繫結:將pl/sql程式中的變數與繫結變數關聯。

--開啟:開啟游標

--執行:在sql引擎中執行sql語句。

--關閉:關閉游標,釋放游標所占用的所有記憶體。

--游標的狀態(例如是否開啟,獲取了多少行資料等)可以使用游標的屬性來獲取。

-----使用顯示游標的乙個完整示例

declare

cursor cur_emp is select * from scott.emp; --定義乙個游標

row_emp cur_emp%rowtype; --基於游標定義乙個記錄

begin

open cur_emp; --開啟游標

fetch cur_emp into row_emp;--從游標中提取一行新增到記錄中

while cur_emp%found --如果記錄成功獲取,返回true

loop

dbms_output.put_line(row_emp.empno || '------'||row_emp.ename);

fetch cur_emp into row_emp;--從游標中提取一行新增到記錄中

end loop;

close cur_emp;--- 關閉游標

end;

---在select語句中提供了for update子句,在我們執行commit或rollback之前,其他人就只能讀這些記錄,而不能修改這些記錄。

---下面是在游標中使用for update子句的兩個示例

--1cursor emp_cur is

select empno, ename,sal from scott.emp where job='manager' for update;

--2cursor emp_cur is

select empno, ename ,sal from emp where job ='manager' for update of sal;

--of 後面是查詢字段列表中的乙個列名.

--如果多表查詢的select語句中使用for update 子句 那麼只有在for update 子句中國引用了某個表的列時,該表中的行才會被鎖住

--例如,在下面的示列中,for update 子句不會鎖住表dept中的任何行;

--這是因為for update 子句只引用了表emp中的列sal,而表dept中的列乙個也沒用被引用。

select * from scott.dept

cursor emp_cur

select d.dname,e.ename,e.sal from scott.dept d, scott.emp e where e.job='manager'and d.deptno =e.deptno for update of e.sal;

----for update 子句的of 列表並不限制我們只能更改列出的列。

----鎖還是放在所有被影響的行上面。

----of 列表只是讓我們更清楚我們需要更改什麼。

----沒有帶of關鍵字,那麼資料庫就會鎖住from 子句中列出的所有表的被影響的行。

-----for update子句後新增乙個nowait 關鍵字,用於告訴oracle 如果表已經被其他使用者鎖住,就不需要等待...

-----一旦乙個帶有for update 的游標被開啟後,游標結果集中的所有的行都會被鎖住,直到當前會話提交了commit語句儲存修改,

-----或使用rollback語句取消修改為止。

-----提交或回滾後, 行上的鎖就被釋放。因此,在commit或rollback後,我們就不能在對forupdate游標的執行fetch了。

-----如果我們在用select。。for update 定義的游標中提取記錄後,需要執行commit或rollback,必須在迴圈或者條件邏輯中加入exit**中斷繼續從游標中提取記錄。

----where current of子句引用的是游標

---下面是乙個使用顯示游標更改資料的完整示例,實現了為雇員中所有部門經理加薪1000的功能;

select *from scott.emp

declare

--定義乙個游標emp_cur,其結果集為雇員中所有的部門經理,游標開啟後會把這些記錄加鎖

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

--給每位部門經理加薪1000

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迴圈僅用在需要處理游標中每一條記錄時)

select *from scott.emp

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;

--我們可以看到游標for迴圈確實很好地簡化了游標的開發,我們不再需要宣告記錄,不再需要open,fetch和close語句,

--不再需要使用%found屬性檢測是否到最後一條記錄,這一切oracle隱式地幫我們完成了。

---。。bulk collect

--可以在select into\fetch into\returning into子句中使用bulk collect

---bulk collect的一些必須記住的規則。

--現在我們用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||'--'||row_emp(i).job);

end loop;

close cur_emp;

end;

顯示游標獲取資料

在oracle中,當我們從pl sql中執行一條select語句時,oracle rdbms 關聯式資料庫管理系統 會為該語句在sga的共享池中分配乙個私有sql區,同時在將查詢結果集放入系統全域性區sga中,以提高訪問和修改結果集的效能。私有sql區包含了該語句的資訊以及結果集的資訊。oracle...

pl sql游標 PL SQL游標 1

pl sql游標 游標 隱式游標 sql返回單行。由oracle server建立。顯式游標 sql重新調整多個記錄行。由使用者建立。游標生命週期 宣告 開啟 獲取 檢查最後一條記錄 關閉 基本語法 declare cursor cursorname param1,param2,is select ...

在PL SQL使用游標獲取資料及動態SQL

1.游標概念 當在pl sql塊中執行dml 增刪改 時,oracle會為其分配上下文區 context area 游標是指向上下文區的指標 2.游標分類 a.隱式游標 a.在pl sql中使用dml語句時自動建立隱式游標 b.隱式游標自動宣告 開啟和關閉,其名為 sql c.通過檢查隱式游標的屬性...