遊標的概念、作用、屬性、查詢操作、可更新的遊標
一、遊標的主要針對操作物件是從資料庫返回的結果集,廣義上可以理解為是從結果集中一行一行讀取資料的方法,一種機制,狹義上也可以將遊標理解為所要操作的結果集,因為在操作的最開始就需要給遊標指定一個要操作的結果集(corsor c is select ....),也可以將遊標理解為操作的每一行的而形成的臨時檔案,裡面存放的是讀取出來的該行的副本,這個臨時檔案提供了向前遍歷和向後遍歷以及處理資料的能力。
二、遊標最常用的作用,就是查詢資料,大多的語言都支援使用遊標來檢索SQL資料庫中的資料,並儲存查詢的結果以供之後使用,比如我們在日常過程中需要重複處理容易個結果集,我們就可以選擇只加載一次結果集,建立一個遊標並反覆使用,這樣就比多次建立結果集效率要高的多。
三、遊標的四個屬性(一下預設curcor_name都為c)
1、%notfound 最近一次fetch後是否取到結果,布林型別,如果有結果就返回true
舉個栗子:
open c;
loop
fetch c into v_name;
exit when(c%notfound);
dbms_output.put_line(v_name.vname);
end loop;
close c;
2、%found 最近一次fetch後是否取到結果,布林型別,如果沒有,則為false
舉個例子:
open c;
while c%found loop
....
fetch c into v_name;
end loop;
close c;
3、%rowcount 返回的是遊標取到的行數 為number型別
舉個栗子:
open c;
loop
fetch c into v_name;
exit when c%rowcount>5;
....
end loop;
close c;
4、%isopen 表示的是此刻否開啟遊標,是布林型別,當開啟時為true,一般用的比較少;
舉個栗子:如果想判斷遊標是否開啟,如果沒有開啟就執行開啟的操作
if not(c%isopen) then
open c;
end if;
fetch c into....;
四、用遊標進行簡單的查詢操作
注意:如果想讓cmd打印出來我們要求的結果,需要提前加上一條語句:set serveroutput on
declare
cursor c is (宣告一個遊標並指向如下查詢語句的結果集)
select * from emp;
v_emp c%rowtype; (生命一個變數,遊標指向的是返回結果集的行)
begin
open c; (開啟遊標後才會執行查詢語句)
fetch c into v_emp; (捕捉到一行結果放到變數v_emp中)
dbms_output.put_line(v_emp.ename); (列印得到的結果中的ename欄位)
close c;
end;
/
五、使用loop迴圈的方式遍歷結果集
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
loop
fetch c into v_emp;
exit when(c%notfound);
dbms_output.put_line(v_emp.ename);
end loop;
close c;
end;
/
(注:如果此處將列印語句與判斷何時退出的語句交換位置,會出現將最後一個查到的資料重新列印一遍的情況)
六、使用while迴圈遍歷得到資料
declare
cursor c is
select * from emp;
v_emp c%rowtype; //使用while遍歷,仍然需要對v_emp進行宣告
begin
open c;
fetch c into v_emp;
while(c%found) loop (噹噹前最近的一次遊標發現了一行的時候執行如下語句)
dbms_output.put_line(v_emp.ename);
fetch c into v_emp;
end loop;
close c;
end;
/
七、使用for迴圈遍歷資料
declare
corsor c is
select * from emp;
begin
for v_emp in c loop
dbms_output.put_line(v_emp.ename);
end loop;
end;
八、帶引數的遊標
declare
cursor c(v_deptno emp.deptno%type,v_job emp.job%type)
is
select ename,sal from emp where deptno = v_deptno and job = v_job;
begin
for v_temp in c(30,'CLERK') loop
dbms_output.put_line(v_temp.ename);
end loop;
end;
/
九、可更新的遊標
declare
cursor c is
select * from emp for update;
begin
for v_temp in c loop;
if(v_temp.sal < 2000) then
update emp set sal = sal*2 where current of c(指當前遊標);
elsif (v_temp.sal = 5000) then
delete from emp where current of c;
end if;
end loop;
commit;
end;