1. 程式人生 > >Oracle 顯式遊標的簡單案例

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月見