PL/SQLの基礎を4日でマスターする【1日目】後編


前編では、

1.変数と定数の定義の仕方
2.条件制御(IF文)

について学習しました。

後編では、条件制御(CASE文)と反復制御(FOR文・WHILE文・NULL文)について見ていきましょう。

0.Agenda

1.Case文
2.Loop文
3.Continue句
4.Null文

1.CASE文

CASE文には以下の2種類があります。

種類 概要  
CASE文   ある値を基に等価比較を行い、特定の処理を行う。
検索CASE文      等価比較以外の検索条件も指定でき、条件を満たすと特定の処理を行う。          

これらCASE文2種類については、まずサンプルコードを見てから説明していきたいと思います。

CASE文

/*
 CASE <選択肢式>
  WHEN <条件文1> THEN
   <処理>
  WHEN <条件文X> THEN
   <処理>
  ELSE
   <処理>
 END CASE;
*/

DECLEAR
 var NUMBER := 20;
BEGIN
 CASE var
  WHEN 10 THEN
   //do something
 WHEN 20 THEN
   //do something
  ELSE
   //do something
END CASE;
END;
/

CASE/WHEN文

/*
 CASE <選択肢式>
  WHEN <条件文1> THEN
   <処理>
  WHEN <条件文X> THEN
   <処理>
  ELSE
   <処理>
 END CASE;
*/

DECLEAR
 var NUMBER := 20;
BEGIN
 CASE var
  WHEN var > 10 THEN
   //do something
 WHEN var > 20 THEN
   //do something
  ELSE
   //do something
END CASE;
END;
/

まず、基本のcase文では、<選択肢式>と結果が等しい場合にのみcaseのなかに入っていけることが分かります。
一方の検索case文では、条件が等しい場合以外(大小の比較)も含めてcase文の中へ入っていき、処理を行うことが可能だということが分かりました。

2.LOOP文

LOOP文の種類としては以下の通りです。

種類     概要   
基本LOOP文     最も基本的なLOOP文。終了条件を指定し、条件に合致するまで繰り返しを行う。
FOR-LOOP文      あらかじめ回数を指定し、決まった回数だけ繰り返し処理を行う。          
WHILE-LOOP文     決められた条件を満たす間、繰り返しを行う。

まず、基本LOOP文について見ていきます。
基本LOOP文では、終了条件を指定することで繰り返し処理が終了します。
繰り返し処理を終了させるには、EXIT句かEXIT WHEN句を指定します。
EXIT句・EXIT-WHEN句の概要は以下の通りです。

種類 概要  
EXIT句   無条件にLOOP文を終了する。
EXIT-WHEN句      LOOPの終了条件を記述し、それを満たせばLOOP文は終了する。          
LOOP文/EXIT句
BEGIN
 LOOP 
  DBMS_OUTPUT.PUT_LINE('OK');
  EXIT;
 END LOOP;
END;
/

EXIT句では、状況に関わらずEXIT句にたどり着くと繰り返し処理が強制終了させられてしまします。
そこで、EXIT-WHEN句を使用することで、指定した条件に合致した場合に処理を終了させることができます。

LOOP文
DECLARE
 c_count NUMBER := 0;
BEGIN
 LOOP
 EXIT WHEN c_count = 3;
 c_count := c_count + 1;
  DBMS_OUTPUT.PUT_LINE('OK');
 END LOOP;
END;
/

このように変数を宣言し、3回繰り返したときに終了するという風に条件を指定することができます。
…が、これ、いちいち変数を宣言しなくてはならずめんどうですよね?
そこで登場するのがFOR-LOOP文です。
FOR-LOOP文では、繰り返し分のなかでカウンターを宣言できるので、若干手間が省けます。

FOR-LOOP文

/*
FOR <ループカウンタ名> IN[REVERSE] <初期値>..<終了値> LOOP
<繰り返したい処理>
END LOOP;
*/

BEGIN
 FOR c IN 0..3 LOOP
  DBMS_OUTPUT.PUT_LINE('OK');
 END LOOP;
END;
/

上のコードは「LOOP文:EXIT/WHEN句」のコードをFOR-LOOPで書き直したものです。
DECLARE部が省かれたことで、スリムなコードになったと思います。

ただし、FOR-LOOP文のカウンタにはいくつか注意点があります。

・ループカウンタ名は宣言部で定義することはできない
・一回ループするごとに1ずつ増える
・ループカウンターに明示的に値を代入することはできない
・ループカウンターはLOOP~END LOOPの間でのみ参照可能。

次に登場するWHILE-LOOP文は、基本ループ文とは違い、処理を行う前に条件式が審査されます。
そのため、上二つのLOOP文とは異なり、処理が一度も実行されないということがありえます。

WHILE
/*
WHILE <条件式> LOOP
<繰り返したい処理>
END LOOP;
*/

DECLARE
c_count NUMBER := 0;
BEGIN
 WHILE c_count < 3 LOOP
  c_count := c_count + 1;
  DBMS_OUTPUT.PUT_LINE('OK');
 END LOOP;
END;
/

上の例文の場合、c_continueが3以上ならばLOOP文の中を通らないということになります。
同様に、ある特定の値の場合だけLoop文の処理をスキップするという制御を行うことができます。
その場合には、continue句を用います。

3.Continue句

Continue句は、Conutinue-END LOOP;の間にある処理をスキップすることができます。
END-LOOPまでスキップし、ループの開始点に制御を移します。
また、WHEN句と組み合わせることで、特定の条件の場合に限り、処理をスキップするという動きが可能です。

CONTINUE-WHEN

/*
CONTINUE WHEN <条件式> 
*/

BEGIN
 FOR c IN 1..3 LOOP 
  DBMS_OUTPUT.PUT_LINE('OK');
  CONTINUE WHEN c = 3;
 END LOOP;
END;
/

4.NULL文

NULL文はプログラム内で、何もしないことを明確にしたい場合に用います。
例えば、IF-ELSE文ないで、ELSEの場合は何もしない場合に、なにも処理を書かなければ、ELSEの場合はなにもしないことになります。
ですが、その書き方をした場合、他の誰かがコードを読んだ場合に「ELSEブロック内に何も書いていないのは書き忘れ?」と思う場合があります。
そのような場合にNULL文を書いておけば、他の第三者は「あ、なにもしないんだな」ということを把握できるわけです。

ではNULL文の使い方を見ていきましょう。

NULL文

DECLARE
 var varchar2(2) := 'OK';
BEGIN 
 IF var = 'OK'
  THEN
   DBMS_OUTPUT.PUT_LINE('OK');
  ELSE
   NULL;
 END IF;
END;
/

5.補足

最初は気づかなかったのですが、環境によってはDBMS_OUTPUT.PUT_LINE()がコンソールに表示されない場合があるようです。
そんな場合は、SET SERVEROUTPUT ON; スクリプトを実行すると表示されるようになります。

SET SERVEROUTPUT ON;

最後に

タイトルに掲げているように、書籍自体は4日で読み終え、一通りは理解していると思うのですが、いかんせん投稿がおいついていないのです...orz
なのでここからは、「○日目に学習した内容」を記事にしていきます。
ということで嘘はついていませんよ!!!(笑)


【参考文献】
『プロとしてのOracle PL/SQL入門』 アシスト教育部 2017年 第3版