跳到主要内容

存储程序使用限制

本文限制适用于所有存储的例程,即存储过程和存储函数。还有一些限制特定于存储函数而非存储过程。存储函数的限制也适用于触发器,但是触发器也有一些特定的限制。

SQL 语句的使用限制

存储程序对 SQL 语句的使用限制如下:

  • 存储例程不允许使用 LOAD DATA 语句。

  • SQL 预处理语句(PREPAREEXECUTEDEALLOCATE PREPARE)可以用于存储过程,但不能用于存储函数或触发器。因此,存储的函数和触发器不能使用动态 SQL。

  • 存储程序中也不允许使用 SQL 预处理语句中所限制使用的语句。但是,异常处理语句 SIGNALRESIGNALGET DIAGNOSTICS 除外,虽然它们不允许作为预处理语句,但是允许在存储程序中使用。

  • 因为本地变量只生效于存储程序执行期间,因此不允许被存储程序内创建的预处理语句所引用。预处理语句只对当前会话有效,而不是所在的存储程序,因此该语句可以在程序结束后执行,而此时变量已不在生效范围中。

  • 在所有存储程序(存储过程和函数、触发器)中,解析器将 BEGIN[WORK] 视作 BEGIN。。。END 块。要在此上下文中启动事务,请使用 START TRANSACTION

存储函数的限制

存储函数中不允许使用以下附加语句或操作:

  • 执行显式或隐式提交或回滚的语句。SQL 标准不要求支持这些语句,该标准规定每个 DBMS 供应商可以自行决定是否加以限制。

  • 返回结果集的语句,例如不包含 INTO var_list 子句的 SELECT 语句和 SHOWEXPLAINCHECK TABLE 等。函数可以使用 SELECT INTO 子句或者使用游标和 FETCH 语句来处理结果集。

  • FLUSH 语句。

  • 存储函数不能用于递归使用。

  • 如果表存在于该函数或触发器的调用语句(用于读取或写入)中,则存储的函数或触发器无法修改该表。

以上限制语句可以在存储过程中使用,但从存储函数或触发器中调用的存储过程除外。例如,如果在存储过程中使用 FLUSH 语句,则无法从存储函数或触发器调用该存储过程。

触发器的限制

触发器具有如下附加限制:

  • 外键操作不会激活触发器。

  • 因为触发器不能返回值,所以不允许包含 RETURN 语句。如果想要立即退出触发器,请使用 LEAVE 语句。

存储例程中的名称冲突

例程的参数、局部变量和表的列名称可以使用同一标识符,嵌套块中也可以使用相同的局部变量名。对于这种标识符不明确情况,遵从以下优先规则:

  • 局部变量一般优先于例程参数或表的列名称。

  • 例程的参数优先于表的列名称。

  • 内部块中的局部变量优先于外部块中的局部变量。