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 语句时,您应该一些额外作用域注意事项:
  • 如果在 FOR 语句中定义了 GOTO 语句,那么必须在同一 FOR 语句内定义标签,除非它在嵌套 FOR 语句或嵌套复合语句中。
  • 如果在复合语句中定义了 GOTO 语句,那么必须在同一复合语句内定义标签,除非它在嵌套 FOR 语句或嵌套复合语句中。
  • 如果在处理程序中定义了 GOTO 语句,那么必须在同一处理程序内定义标签并遵循其他作用域规则。
  • 如果在处理程序外定义了 GOTO 语句,那么不能在处理程序内定义标签。
  • 如果未在 GOTO 语句可访问的作用域内定义标签,那么会返回错误 (SQLSTATE 42736)。