存储程序使用限制
本文限制适用于所有存储的例程,即存储过程和存储函数。还有一些限制特定于存储函数而非存储过程。存储函数的限制也适用于触发器,但是触发器也有一些特定的限制。
SQL 语句的使用限制
存储程序对 SQL 语句的使用限制如下:
-
存储例程不允许使用
LOAD DATA语句。 -
SQL 预处理语句(
PREPARE、EXECUTE、DEALLOCATE PREPARE)可以用于存储过程,但不能用于存储函数或触发器。因此,存储的函数和触发器不能使用动态 SQL。 -
存储程序中也不允许使用 SQL 预处理语句中所限制使用的语句。但是,异常处理语句
SIGNAL、RESIGNAL和GET DIAGNOSTICS除外,虽然它们不允许作为预处理语句,但是允许在存储程序中使用。 -
因为本地变量只生效于存储程序执行期间,因此不允许被存储程序内创建的预处理语句所引用。预处理语句只对当前会话有效,而不是所在的存储程序,因此该语句可以在程序结束后执行,而此时变量已不在生效范围中。
-
在所有存储程序(存储过程和函数、触发器)中,解析器将
BEGIN[WORK]视作BEGIN。。。END块。要在此上下文中启动事务,请使用START TRANSACTION。
存储函数的限制
存储函数中不允 许使用以下附加语句或操作:
-
执行显式或隐式提交或回滚的语句。SQL 标准不要求支持这些语句,该标准规定每个 DBMS 供应商可以自行决定是否加以限制。
-
返回结果集的语句,例如不包含
INTO var_list子句的SELECT语句和SHOW、EXPLAIN和CHECK TABLE等。函数可以使用SELECT INTO子句或者使用游标和FETCH语句来处理结果集。 -
FLUSH语句。 -
存储函数不能用于递归使用。
-
如果表存在于该函数或触发器的调用语句(用于读取或写入)中,则存储的函数或触发器无法修改该表。
以上限制语句可以在存储过程中使用,但从存储函数或触发器中调用的存储过程除外。例如,如果在存储过程中使用 FLUSH 语句,则无法从存储函数或触发器调用该存储过程。
触发器的限制
触发器具有如下附加限制:
-
外键操作不会激活触发器。
-
因为触发器不能返回值,所以不允许包含
RETURN语句。如果想要立即退出触发器,请使用LEAVE语句。
存储例程中的名称冲突
例程的参数、局部变量和表的列名称可以使用同一标识符,嵌套块中也可以使用相同的局部变量名。对于这种标识符不明确情况,遵从以下优先规则:
-
局部变量一般优先于例程参数或表的列名称。
-
例程的参数优先于表的列名称。
-
内部块中的局部变量优先于外部块中的局部变量。