--在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;
顯示游標獲取資料 PL SQL
在oracle中,當我們從pl sql中執行一條select語句時,oracle rdbms 關聯式資料庫管理系統 會為該語句在sga的共享池中分配乙個私有sql區,同時在將查詢結果集放入系統全域性區sga中,以提高訪問和修改結果集的效能。私有sql區包含了該語句的資訊以及結果集的資訊。oracle...
Oracle 顯示游標
游標的基本原理 在oracle中,在執行乙個有select insert update和delete語句pl sql塊時,oracle會在記憶體中為其分配乙個緩衝區,將執行結果放在這個緩衝區中,而游標是該去的乙個指標。游標分類 靜態游標 動態游標。靜態游標又分隱式游標和顯示游標。顯示游標的使用步驟 ...
Oracle 顯示游標
create or replace procedure 顯示游標更新 as select taid,taname,bqid from table3 new taid number cursor cur table is 顯示宣告游標 select taid from table3 where tai...