2015年11月29日日曜日

PLSQL 制御文 ~GOTO文とラベル、NULL文~

PLSQLではGOTO文が使用できます。
しかし、他の言語同様に多用するのは厳禁です。

11g以前ではループのスキップにcontinue文が使用できないので、GOTO文を使用する機会があるかと思います。

GOTO文とラベル、NULL文の基本的な使い方


まずはGOTO文とラベルの使い方です。
ラベルは「「<<ラベル名>>」と定義します。
GOTO文で「GOTO ラベル名;」とすることで、指定したラベルに制御を移すことができます。
処理がないラベルを定義する事はできません。
ラベルの処理が何もない場合はNULL文を使用します。 NULL文は何もしないステートメントを意味します。
DECLARE
    num NUMBER := &任意の数値;
BEGIN
    
    IF (num < 10) THEN
        GOTO under_ten;
    ELSE
        GOTO over_ten;
    END IF;
    
    <<under_ten>>
        SYS.DBMS_OUTPUT.PUT_LINE('10以下');
    
    <<over_ten>>
        NULL;
END;

ループのContinue文の代わりにGOTO文を使用する(11g以前)


11g以前ではContinue文が使用できないので、ループのスキップにGOTO文を使用することがあります。
※11g以降はcontinue文を使用したほうがよいと思います。
Continue文についてはコチラ 「PLSQL 制御文 ~LOOP文~

以下はGOTO文を使用した、ループのスキップです。
ループカウンタが偶数の場合は、ループ処理をスキップします。
DECLARE
    
BEGIN

    FOR num IN 1..10 LOOP
        IF (num Mod 2 = 0) THEN
            GOTO continue;
        END IF;
        
        SYS.DBMS_OUTPUT.PUT_LINE(num);
        
        <<continue>>
            NULL;
    END LOOP;

END;

ループラベル


ループ開始の直前にラベルを付けるとそのラベルは「ループラベル」になります。
11g以降ではContinue文が使用できますが、「Continue ラベル;」や「Continue ラベル WHEN 条件;」と書くことで、スキップするループを指定することができます。
同様にEXIT文についても「Exit ラベル;」や「Exit ラベル WHEN 条件;」と書くことで、終了するループを指定することができます。
ループをネストした多重ループで、スキップしたいループや終了したいループを指定するときに使用します。
DECLARE
 
BEGIN

    <<loop_1>>
    FOR i IN 1..3 LOOP
         
        <<loop_2>>
        FOR j IN 1..3 LOOP
            
            <<loop_3>>       
            FOR k iN 1..3 LOOP
                dbms_output.put_line('i=' || i || ', j=' || j || ', k=' || k );
                
                --j=2はループ2をスキップ
                CONTINUE loop_2 WHEN ( j = 2);
                --j=3はループ1をスキップ
                IF (j = 3) THEN
                    CONTINUE loop_1;
                END IF;
                
                
                --i=2はループ3を終了
                EXIT loop_3 WHEN ( i = 3);
                --i=3はループ2を終了
                IF (i = 3) THEN
                    EXIT loop_2;
                END IF;
               
            
            END LOOP; --loop1
            
        END LOOP; --loop2
    
    END LOOP; --loop3

   dbms_output.put_line('ループ終了');
END;
出力結果
i=1, j=1, k=1
i=1, j=1, k=2
i=1, j=1, k=3
i=1, j=2, k=1
i=1, j=3, k=1
i=2, j=1, k=1
i=2, j=1, k=2
i=2, j=1, k=3
i=2, j=2, k=1
i=2, j=3, k=1
i=3, j=1, k=1
i=3, j=2, k=1
i=3, j=3, k=1
ループ終了

0 件のコメント: