顯示游標獲取資料

2021-07-27 03:35:25 字數 4632 閱讀 9264

--在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...