順次制御文

sequential control statementsであるGOTO文とNULL文は、PL/SQLプログラミングではIF文やLOOP文ほど重要ではありません。

指定した文に移動するGOTO文が必要となることはほとんどありません。ただし、これを使用すると論理を単純化できる場合もあります。

何も実行しないNULL文には、条件文の意味とアクションを明確にすることによって、コードをわかりやすくする効果があります。

ここでのトピック

GOTO文

GOTO文は無条件に制御をラベルに移します。ラベルは有効範囲の中で他と重複しないもので、実行可能文かPL/SQLブロックの前に置かれている必要があります。GOTO文が実行されると、ラベルが付けられた文またはブロックに制御が移ります。

GOTO文の制限については、「GOTO文」を参照してください。

GOTO文の使用は最小限にしてください(多用すると、コードの理解やメンテナンスが困難になります)。深いネスト構造から例外ハンドラに制御を移す場合、GOTO文は使用しないでください。かわりに、例外を呼び出してください。PL/SQLの例外処理メカニズムの詳細は、「PL/SQLのエラー処理」を参照してください。

このGOTO文は、参照されたラベルが置かれている最初の外側のブロックに制御を移しています。

NULL文

NULL文は、後続の文に制御を移すのみです。一部の言語では、このような命令をno-op(何もしない)と呼びます。

NULL文は、次のように使用できます。

  • GOTO文のターゲットを提供する

  • 条件文の意味とアクションを明確にすることで、わかりやすくする

  • プレースホルダとスタブ・サブプログラムを作成する

  • 考慮はするがアクションは不要なことを示す

ノート:

NULL文を使用する場合に警告が有効になっていると、unreachable codeという警告が発生する可能性があります。警告の詳細は、「コンパイル時の警告」を参照してください。

例5-30 アクションを実行しないことを明示するNULL文

NULL文によって、販売員のみがコミッションを受け取ることを明確にしています。

DECLARE
  v_job_id  VARCHAR2(10);
   v_emp_id  NUMBER(6) := 110;
BEGIN
  SELECT job_id INTO v_job_id
  FROM employees
  WHERE employee_id = v_emp_id;
  
  IF v_job_id = 'SA_REP' THEN
    UPDATE employees
    SET commission_pct = commission_pct * 1.2;
  ELSE
    NULL;  -- Employee is not a sales rep
  END IF;
END;
/

例5-31 サブプログラム作成時のプレースホルダとしてのNULL文

NULL文を使用して、このサブプログラムをコンパイルできるようにしています。今後、実際の本体を記述します。

CREATE OR REPLACE PROCEDURE award_bonus (
  emp_id NUMBER,
  bonus NUMBER
) AUTHID DEFINER AS
BEGIN    -- Executable part starts here
  NULL;  -- Placeholder
  -- (raises "unreachable code" if warnings enabled)
END award_bonus;
/

例5-32 単純なCASE文のELSE句でのNULL文

NULL文によって、A、B、C、D、F以外のgradeではアクションを実施しないことを示しています。

CREATE OR REPLACE PROCEDURE print_grade (
  grade CHAR
) AUTHID DEFINER AS
BEGIN
  CASE grade
    WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
    WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
    WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
    WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
    WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
    ELSE NULL;
  END CASE;
END;
/
BEGIN
  print_grade('A');
  print_grade('S');
END;
/

結果:

Excellent