GOTO Statement
The GOTO statement branches to a label unconditionally. The label must be exclusive within its scope and should precede an executable statement or a PL/SQL block. If executed, the GOTO statement transfers control to the labeled statement or block. In the following illustration, you go to an executable statement farther down in a series of statements:
BEGIN
...
GOTO insert_row;
...
<>
INSERT INTO emp VALUES...
END;
In the next illustration, you go to a PL/SQL block farther up in a series of statements:
BEGIN
...
<>
BEGIN
UPDATE emp SET ...
...
END;
...
GOTO update_row;
...
END;
The label end_loop in the example below is illegal as it does not precede an executable statement:
DECLARE
done BOOLEAN;
BEGIN
...
FOR i IN 1..50 LOOP
IF done THEN
GOTO end_loop;
END IF;
...
<> -- illegal
END LOOP; -- not an executable statement
END;
To debug the last illustration, now add the NULL statement, as shown:
FOR i IN 1..50 LOOP
IF done THEN
GOTO end_loop;
END IF;
...
<>
NULL; -- an executable statement
END LOOP;
As the following illustration shows, a GOTO statement can branch to an enclosing block from the present block:
DECLARE
my_ename CHAR(10);
BEGIN
<>
SELECT ename INTO my_ename FROM emp WHERE...
BEGIN
...
GOTO get_name; -- branch to enclosing block
END;
END;
Restrictions
Some likely destinations of a GOTO statement are illegal. Particularly, a GOTO statement cannot branch into an IF statement, LOOP statement, or sub-block. For illustration, the following GOTO statement is illegal:
BEGIN
...
GOTO update_row; -- illegal branch into IF statement
...
IF valid THEN
...
<>
UPDATE emp SET...
END IF;
END;
A GOTO statement also cannot branch from one IF statement clause to another, as the following illustration shows:
BEGIN
...
IF valid THEN
...
GOTO update_row; -- illegal branch into ELSE clause
ELSE
...
<>
UPDATE emp SET...
END IF;
END;
The next illustration shows that a GOTO statement cannot branch from an enclose block into a sub-block:
BEGIN
...
IF status = ’OBSOLETE’ THEN
GOTO delete_part; -- illegal branch into sub-block
END IF;
...
BEGIN
...
<>
DELETE FROM parts WHERE...
END;
END;
A GOTO statement also cannot branch out of a subprogram, as the following illustration shows:
DECLARE
...
PROCEDURE compute_bonus (emp_id NUMBER) IS
BEGIN
...
GOTO update_row; -- illegal branch out of subprogram
END;
BEGIN
...
<>
UPDATE emp SET...
END;
Finally, the GOTO statement cannot branch from an exception handler into the present block. For illustration, the following GOTO statement is illegal:
DECLARE
...
pe_ratio REAL;
BEGIN
...
SELECT price / NVL(earnings, 0) INTO pe_ratio FROM ...
<>
INSERT INTO stats VALUES (pe_ratio, ...);
EXCEPTION
WHEN ZERO_DIVIDE THEN
pe_ratio := 0;
GOTO insert_row; -- illegal branch into current block
END;
Though, a GOTO statement can branch from an exception handler into the enclosing block.