Oracle基本修練: PL/SQL LOOPS

ChunJen Wang
jimmy-wang
Published in
7 min readSep 12, 2021

迴圈幾乎是所有程式開發的基本元件,搭配上條件判斷、變數使用,我們可以做到許多事情,而SQL也透過PL/SQL結構,賦予其更強大的功能!

Content

Let’s Start!

Basic LOOP statement

<<label>> LOOP 
statements;
END LOOP loop_label;

這是最基本的LOOP結構,不論採用FOR LOOPWHILE LOOP ,都需要有LOOP+END LOOP的關鍵字來涵蓋。

迴圈最大的特色就是,會持續循環直到條件達成,而我們也可以採用EXITEXIT WHEN 來告訴程式終止循環,此時,LOOP執行過程一碰到EXIT 便會退出循環。

LOOP 
IF condition THEN
EXIT;
END IF;
END LOOP;

用一個簡單的範例就如

DECLARE 
l_counter NUMBER := 0; -- 初始化變量 l_counter為零
BEGIN
LOOP
l_counter := l_counter + 1; -- 迴圈中每執行一次 l_counter就+1
IF l_counter > 3 THEN -- 直到 l_counter 大於 3 進IF條件
EXIT;
END IF;
dbms_output.put_line( 'Inside loop:' || l_counter ) ;
END LOOP;
dbms_output.put_line( 'After loop:' || l_counter );
END;

執行結果為

相同的輸出結果,我們也可以採用EXIT WHEN

DECLARE
l_counter NUMBER := 0;
BEGIN
LOOP
l_counter := l_counter + 1;
EXIT WHEN l_counter > 3; -- 直到 l_counter 大於 3 就EXIT
dbms_output.put_line( 'Inside loop: ' || l_counter ) ;
END LOOP;
dbms_output.put_line( 'After loop: ' || l_counter );
END;

Nested loops

就如經典題目two sum,在初學程式時,我們會採用雙層迴圈來進行解題,而PL/SQL也可以執行Nested loops。

DECLARE
l_i NUMBER := 0;
l_j NUMBER := 0;
BEGIN
<<outer_loop>>
LOOP
l_i := l_i + 1;
EXIT outer_loop WHEN l_i > 2;
dbms_output.put_line('Outer counter(i) ' || l_i);
-- reset inner counter
l_j := 0;
<<inner_loop>> LOOP
l_j := l_j + 1;
EXIT inner_loop WHEN l_j > 3;
dbms_output.put_line(' Inner counter(j) ' || l_j);
END LOOP inner_loop;
END LOOP outer_loop;
END;

Numeric FOR LOOP statement

為了給予LOOP指定執行次數,我們會採用index來告訴LOOP要執行多久。
其基本結構為

FOR index IN lower_bound .. upper_bound 
LOOP
statements;
END LOOP;

一個簡單的範例如

DECLARE
l_step PLS_INTEGER := 2; -- 搭配loop進行計算的變量宣告
BEGIN
FOR l_counter IN 1..5 LOOP
dbms_output.put_line (l_counter*l_step);
END LOOP;
END;

特別的用法是,在FOR LOOP可以透過REVERSE 來進行倒敘的用法。

BEGIN
FOR l_counter IN REVERSE 1..3
LOOP
DBMS_OUTPUT.PUT_LINE( l_counter );
END LOOP;
END;

WHILE loop

與for迴圈不同的是,while可以無限執行直到條件達成,相對給予index的for loop,兩者使用場景就會有所不同。而與LOOP一樣的地方是,若需要提前終止,也可以採用EXIT,EXIT WHEN語句。

WHILE condition 
LOOP
statements;
END LOOP;

無限執行為如果條件為TRUE,則執行循環。如果是FALSENULL,則終止循環。

DECLARE
n_counter NUMBER := 1;
BEGIN
WHILE n_counter <= 5 -- 反覆執行直到n_counter超過5
LOOP
DBMS_OUTPUT.PUT_LINE( 'Counter : ' || n_counter );
n_counter := n_counter + 1;
EXIT WHEN n_counter = 3; -- 如果n_counter為3就跳出 END LOOP;
END;

CONTINUE

CONTINUECONTINUE WHEN語句分別為無條件有條件地退出當前LOOP,直接接續下一輪循環繼續執行。

通常是用在搭配條件判斷,整合進LOOP來做使用。並適用於所有LOOP的結構。

BEGIN
FOR n_index IN 1 .. 10
LOOP
IF MOD( n_index, 2 ) = 1 THEN -- MOD是計算餘數的function。
CONTINUE; -- 遇到奇數就跳過!
END IF;
DBMS_OUTPUT.PUT_LINE( n_index );
END LOOP;
END;

與一般CONTINUE相反的就是CONTINUE WHEN

BEGIN
FOR n_index IN 1 .. 10
LOOP
CONTINUE
WHEN
MOD( n_index, 2 ) = 1; -- 遇到奇數就CONTINUE(跳過)!
DBMS_OUTPUT.PUT_LINE( n_index );
END LOOP;
END;

--

--

ChunJen Wang
jimmy-wang

嗨,歡迎你的到來,我目前在銀行擔任DS。過去曾做過銀行大型專案BA,也曾在轉職科技業DE中踢了鐵板,相信每一個人都有自己要走的路,而努力的過程,可以讓我們離心中理想更接近,如果我的文章能帶給你一些啟發與幫助,別忘了幫我在文章底下按下拍手~^^