SQL プロシージャーの GOTO ステートメント

GOTO ステートメントは、単純明快でしかも基本的な制御フローのステートメントであり、制御のフロー内での無条件の変更の原因となります。

これは、SQL プロシージャーに定義されているラベルを使用して特定のユーザー定義ロケーションへのブランチを設定するのに使用します。

GOTO ステートメントの使用は、一般にプログラミングの手法としては粗悪なものと考えられており、推奨されていません。 GOTO を広範囲にわたって使用すると、判読不能なコードにつながる可能性が高くなります。プロシージャーが長大になるときは特にそうです。 さらに、実行パスを制御するために利用できるより優れたステートメントがあるので、GOTO は必要ありません。 GOTO を使用することが必要になるような状況は特にありません。 つまり、便宜上使用される場合のほうが多いということです。

GOTO ステートメントを使用した SQL プロシージャーの例を以下に示します。
  CREATE PROCEDURE adjust_salary ( IN p_empno CHAR(6),
  		                   IN p_rating INTEGER,
				   OUT p_adjusted_salary DECIMAL (8,2) )
  LANGUAGE SQL
  BEGIN
    DECLARE new_salary DECIMAL (9,2);
    DECLARE service DATE;  -- start date

    SELECT salary, hiredate INTO v_new_salary, v_service
      FROM employee
         WHERE empno = p_empno;

    IF service > (CURRENT DATE - 1 year) THEN
      GOTO exit;                   
    END IF;

    IF p_rating = 1 THEN
      SET new_salary = new_salary + (new_salary * .10);  
    END IF;

    UPDATE employee SET salary = new_salary WHERE empno = p_empno;

  exit: 
    SET p_adjusted_salary = v_new_salary;


  END

この例は、GOTO ステートメントの効果的な使用方法を示しています。特定の論理を実行しない一方で、他の論理はこれまでどおり実行されるようにするために、プロシージャーまたはループのほぼ終了地点へスキップします。

GOTO ステートメントの使用時には、有効範囲に関する次のようないくつかの追加の考慮事項があることに注意する必要があります。
  • GOTO ステートメントを FOR ステートメント内で定義する場合、ネストされている FOR ステートメントまたはネストされているコンパウンド・ステートメント内にあるのでない限り、同じ FOR ステートメントの内側でラベルを定義しなければなりません。
  • GOTO ステートメントをコンパウンド・ステートメント内で定義する場合、ネストされている FOR ステートメントまたはネストされているコンパウンド・ステートメント内にあるのでない限り、同じコンパウンド・ステートメント内部でラベルを定義しなければなりません。
  • GOTO ステートメントをハンドラーで定義する場合、他の有効範囲の規則に従って、同じハンドラーでラベルを定義しなければなりません。
  • GOTO ステートメントをハンドラー外で定義する場合、ハンドラーの内部でラベルを定義してはなりません。
  • GOTO ステートメントが到達できる有効範囲内でラベルが定義されていない場合、 エラーが戻されます (SQLSTATE 42736)。