今年春節算是休了個長假,調整好心態,迎接新一年的挑戰。
今天來說下Oracle中的循環迭代處理,因為從自己的博客統計中看到,不少網友都搜索了關鍵字"SQL FOR循環",所以打算在這里說下個人的理解。
PL/SQL也和我們常用的編程語言一樣,提供了While、For等循環,我們建幾個例子來說明演示下。
首先是While循環:
--while循環 procedure loop_while ( start_value in number, end_value in number ) is current_value number := start_value; begin
while current_value <=end_value loop dbms_output.put_line('now number:' || current_value); current_value:=current_value+1; end loop; end loop_while;
指定循環的初始值和結束值之后,就可以看到將這2個值之間的數字一行行打印出來了;當然只要while循環條件的求值結果是true,循環就會繼續下去,
如果求值條件為false或者null,循環就會終止。這個循環條件每執行一次循環體之前都會先進行判斷,因此while循環並不能保證循環體一定能被執行。
所以如果我們無法提前預知所需要巡檢的次數的情況下,就可以使用While來進行循環處理。
For循環有2種,分別是數值型FOR循環和游標型FOR循環:
--數值型For循環 procedure loop_num_for ( lowest in number, highest in number ) is begin FOR even_number in lowest .. highest --升序 loop --處理非平滑增長的索引 if mod(even_number,2)=0 then dbms_output.put_line('now number:' || even_number); end if; end loop; end loop_num_for;
這種循環在開始的時候就已經知道循環的次數了,注意這里不需要聲明循環索引,因為PL/SQL會自動隱式的用一個integer類型的局部變量作為它的循環索引;
如果要降序循環,必須加上reverse關鍵字,並且循環上邊界和下邊界的順利無需改變:
FOR even_number in reverse lowest .. highest loop dbms_output.put_line('now number:' || even_number); end loop;
另外需要說明的是,數值型FOR循環中,索引總是以1為單位遞增或遞減,所以如果我們的循環條件並非如此理想的平滑增長,我們就必須用一些邏輯代碼或者技巧來
達到我們的目的。
如果我們需要對很多行記錄做處理時,就可以使用游標型FOR循環:
--游標型For循環 procedure loop_cursor_for is begin declare cursor userinfo_cur is select * from userinfo_table; begin FOR userinfo_rec in userinfo_cur loop dbms_output.put_line('username is:' || userinfo_rec.user_name); end loop; end; end loop_cursor_for;
當游標中的所有記錄都取出來后,FOR循環就會自動終止,這里不用顯示OPEN、CLOSE游標,PL/SQL引擎會自動處理。
上面的循環語句都可以用EXIT 或者 EXIT WHEN來終止其循環,但最好不要這樣做,因為這樣可能會造成循環的邏輯出現問題,最終造成SQL代碼難於跟蹤和調試。
最后附上測試用的SQL:

create or replace package body LOOP_TEST_DEMO IS --while循環 procedure loop_while(start_value in number, end_value in number) is current_value number := start_value; begin while current_value <= end_value loop dbms_output.put_line('now number:' || current_value); current_value := current_value + 1; end loop; end loop_while; --數值型For循環 procedure loop_num_for(lowest in number, highest in number) is begin FOR even_number in lowest .. highest --升序 loop --dbms_output.put_line(even_number); --處理非平滑增長的索引 if mod(even_number, 2) = 0 then dbms_output.put_line('now number:' || even_number); end if; end loop; --降序 FOR even_number in reverse lowest .. highest loop dbms_output.put_line('now number:' || even_number); end loop; end loop_num_for; --游標型For循環 procedure loop_cursor_for is begin declare cursor userinfo_cur is select * from greenet_user_info; begin FOR userinfo_rec in userinfo_cur loop dbms_output.put_line('username is:' || userinfo_rec.user_name); end loop; end; end loop_cursor_for; end LOOP_TEST_DEMO;