Oracle 顯式遊標的簡單案例
想想上一篇部落格好像發了還沒幾天,結果現在就已經月底了,忙碌的10月呀,忙碌的青春。。
暫時也沒什麼東西特別想寫的其實,想想前兩週在圖書館的時候看到本PL/SQL程式設計,簡單看了下顯式遊標,根據自己日常的應用,弄幾個簡單的案例發一下,應該對Oracle的顯式遊標的有些幫助。
環境不想單獨分點了,還是公司標配的聯想thinkpad,win10,Oracle Database 11g r2,plsql12,谷歌瀏覽器,搜狗輸入法。。
1、小技巧,也是看下面之前要知道的
1.1 dbms_output.put_line('輸出內容');
雖然很多人應該都有在用,但還是說一下吧,這是Oracle自帶的輸出字串的方法,下面截圖說明一下效果。
1.1.1 在plsql 的 SQL視窗中
如下圖,細心的小夥伴應該都有發現,SQL視窗左上角會有三個小標籤頁,預設顯示的是SQL標籤頁,我們在SQL視窗執行下圖1的程式碼的時候,就可以切換到輸出視窗檢視輸出的結果。
1.1.2 在命令視窗中(sqlplus同理)
在命令視窗中,預設輸出功能是關閉的,所以我們在一個命令視窗使用輸出功能之前,需要先開啟輸出功能,然後再XXX,RT。但有個有意思的地方沒搞清楚,命令應該是set serveroutput on,但是不知道為啥用set serverout on 也行,這裡就不多說了。。。
1.2 connect by level <= num
這個涉及到Oracle的層級查詢,說起來可能說到晚上9點都說不完,我就直接貼一下這次中用到的那句sql 的結果,,如下圖的條件level <= 5就會產生一個 1~5 的序列,後面也將直接用這種sql來構造資料進行遍歷
2、小小小案例
2.1 遍歷輸出
就按照上面的查詢,定義一個遊標,然後進行遍歷,獲取到每一行的值,進行輸出
declare cursor lr_num is --定義一個遊標,名為:lr_num select level lv from dual connect by level <= 5; --這段查詢即為遊標lr_num的具體內容 v_num lr_num%rowtype; --定義一個變數v_num,資料型別為遊標 lr_num 的 %ROWTYPE,即lr_num的一行 begin open lr_num; --開啟遊標lr_num loop --開始迴圈 fetch lr_num into v_num; --把遊標 lr_num 中的next一行資料 into 到變數 v_num 中 exit when lr_num%notfound; --如果 lr_num 中找不到next一行資料,即退出迴圈 dbms_output.put_line(v_num.lv); --輸出 v_num 變數中的 lv 欄位的值 end loop; --結束迴圈 close lr_num; --關閉遊標 end; /
執行後看下輸出視窗:
上面是比較完整的遍歷的過程,再說下用while迴圈和for迴圈遍歷的方法,執行後輸出的結果是一模一樣的,就不截圖了
--1.1 while迴圈實現(效果同上)
declare
cursor lr_num is
select level lv from dual connect by level <= 5;
v_num lr_num%rowtype;
begin
open lr_num; --開啟遊標
fetch lr_num into v_num; --取一條資料插入v_num
while lr_num%found loop --如果能取到資料,開始迴圈
dbms_output.put_line(v_num.lv); --輸出取到的資料中的numer欄位
fetch lr_num into v_num; --取出下一條資料插入v_num,然後迴圈上面部分
end loop; --結束迴圈
close lr_num; --關閉遊標
end;
/
--1.2 for迴圈遍歷遊標的方法(效果同上)
declare
cursor lr_num is
select level lv from dual connect by level <= 5;
begin
for v_num in lr_num loop --開始迴圈,自動開啟遊標,並按行依次把資料賦給形參v_num,然後迴圈體裡面就針對v_num進行操作即可
dbms_output.put_line(v_num.lv); --輸出v_num中的numer
end loop; --遍歷完遊標後自動關閉遊標並結束迴圈
end;
/
上面三種遍歷方法,就易用程度來說肯定是for迴圈比較好,程式碼也短,理解也簡單。所以後面我也直接用for迴圈演示啦
2.2 遍歷求和
還是開始的那個遊標內容,進行求和,思路就是遍歷相加嘛,每次相加的值存到變數cnt中,,看程式碼,再看輸出的結果
--2、遍歷,累加
declare
cursor lr_num is
select level lv from dual connect by level <= 5;
cnt number(8) := 0 ; --累加值,初始化為0
begin
for v_num in lr_num loop
cnt := cnt + v_num.lv; --累加
dbms_output.put_line('當前數字為:' || v_num.lv || ', 累加結果為:' || cnt); --輸出
end loop;
end ;
/
2.3 顯式遊標中變數的使用
像之前我們的遊標都是寫死level <= 5, 那遊標的資料就是死資料,每次都是固定的資料。但如果想通過傳遞引數的方式去改變查詢的條件,就可以像下面,定一個引數ln_num,然後查詢中level <= ln_num,這樣,每次開啟遊標呼叫查詢的時候,ln_num的值就直接影響查詢的結果,看程式碼及結果
--3、顯式遊標中的變數的使用
declare
ln_num number(8);
cursor lr_num is
select level lv from dual connect by level <= ln_num;
begin
--第一次,5條
ln_num := 5 ;
--此時開啟遊標,會執行遊標的查詢,此時ln_num為5,查到的結果即為5條
for v_num in lr_num loop
dbms_output.put_line('第1次遍歷:' || v_num.lv);
end loop;
--第二次,7
ln_num := 7 ;
--此時開啟遊標,會執行遊標的查詢,此時ln_num為7,查到的結果即為7條
for v_num in lr_num loop
dbms_output.put_line('第2次遍歷:' || v_num.lv);
end loop;
end ;
/
2.4 引數化顯式遊標
這個跟上面的其實賊像,都是通過外部引數來控制遊標的查詢條件,達到改變遊標的查詢結果的效果,但是引數化顯式遊標更像是傳參,遊標上會寫一個形式引數,呼叫的時候通過這個往這個形式引數中傳參,就類似呼叫函式時往函式裡面傳遞引數,程式碼及效果如下:
--4、引數化顯式遊標
declare
cursor lr_num(an_num number default 3) is
select level lv from dual connect by level <= an_num;
v_num lr_num%rowtype;
begin
--第一次,預設,default為3
for v_num in lr_num loop
dbms_output.put_line('第1次遍歷:' || v_num.lv);
end loop;
--第二次,傳參指定,5條
for v_num in lr_num(5) loop
dbms_output.put_line('第2次遍歷:' || v_num.lv);
end loop;
end ;
/
好了,就寫這麼多吧,10月沒幾天了,珍惜時間,早睡早起。11月見