GOTO文

GOTO文は、ラベルの付いたブロックまたは文に制御を移します。

GOTO文の制限

GOTO文によってカーソルFOR LOOP文が途中で終了されると、カーソルはクローズされます。

  • GOTO文は、IF文、CASE文、LOOP文またはサブブロックには制御を移せません。

  • GOTO文では、あるIF文の句から別の句へ制御を移したり、あるCASE文のWHEN句から別の句へ制御を移すことはできません。

  • GOTO文では、サブプログラムの外に制御を移せません。

  • GOTO文では、例外ハンドラに制御を移せません。

  • GOTO文は、例外ハンドラからカレント・ブロックに制御を戻すことはできません(ただし、例外ハンドラから外側のブロックに制御を移すことはできます)。

ここでのトピック

構文

goto_statement ::=

セマンティクス

goto_statement

label

ブロックまたは文を識別します(「plsql_block ::=」「statement ::=」、および「label」を参照)。

labelがカレント・ブロックにない場合、GOTO文は外側のブロックのうちlabelが存在する最初のものに制御を移します。

例14-31 GOTO文

ラベルは文の前に配置できます。

DECLARE
  p  VARCHAR2(30);
  n  PLS_INTEGER := 37;
BEGIN
  FOR j in 2..ROUND(SQRT(n)) LOOP
    IF n MOD j = 0 THEN
      p := ' is not a prime number';
      GOTO print_now;
    END IF;
  END LOOP;

  p := ' is a prime number';
 
  <<print_now>>
  DBMS_OUTPUT.PUT_LINE(TO_CHAR(n) || p);
END;
/
 

結果:

37 is a prime number

例14-32 不適切なラベル配置

ラベルはブロックの前または文の前にのみ配置できます。

DECLARE
  done  BOOLEAN;
BEGIN
  FOR i IN 1..50 LOOP
    IF done THEN
       GOTO end_loop;
    END IF;
    <<end_loop>>
  END LOOP;
END;
/
 

結果:

  END LOOP;
  *
ERROR at line 9:
ORA-06550: line 9, column 3:
PLS-00103: Encountered the symbol "END" when expecting one of the following:
( begin case declare exit for goto if loop mod null raise
return select update while with <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
continue close current delete fetch lock insert open rollback
savepoint set sql run commit forall merge pipe purge

例14-33 GOTO文によるラベル付きのNULL文への移動

ラベルはNULL文の前に配置できます。

DECLARE
  done  BOOLEAN;
BEGIN
  FOR i IN 1..50 LOOP
    IF done THEN
      GOTO end_loop;
    END IF;
    <<end_loop>>
    NULL;
  END LOOP;
END;
/

例14-34 GOTO文による外側のブロックへの制御の移動

GOTO文は、カレント・ブロックから外側のブロックに制御を移すことができます。

DECLARE
  v_last_name  VARCHAR2(25);
  v_emp_id     NUMBER(6) := 120;
BEGIN
  <<get_name>>
  SELECT last_name INTO v_last_name
  FROM employees
  WHERE employee_id = v_emp_id;
  
  BEGIN
    DBMS_OUTPUT.PUT_LINE (v_last_name);
    v_emp_id := v_emp_id + 5;
 
    IF v_emp_id < 120 THEN
      GOTO get_name;
    END IF;
  END;
END;
/
 

結果:

Weiss

例14-35 GOTO文によるIF文内への無効な制御の移動

GOTO文がIF文内に制御を移しているため、エラーが発生します。

DECLARE
  valid BOOLEAN := TRUE;
BEGIN
  GOTO update_row;
  
  IF valid THEN
  <<update_row>>
    NULL;
  END IF;
END;
/
 

結果:

  GOTO update_row;
  *
ERROR at line 4:
ORA-06550: line 4, column 3:
PLS-00375: illegal GOTO statement; this GOTO cannot branch to label
'UPDATE_ROW'
ORA-06550: line 6, column 12:
PL/SQL: Statement ignored

関連トピック