15.2.1 调用语句
CALL sp_name([parameter[,...]])
CALL sp_name[()]
CALL
语句调用之前使用CREATE PROCEDURE
定义的存储程序。
不带参数的存储程序可以不使用括号调用。例如,CALL p()
和 CALL p
等价。
CALL
可以通过声明为OUT
或 INOUT
的参数将值传回调用者。程序返回时,客户端程序也可以获取最后一个语句执行的行数:在 SQL 层面,可以调用ROW_COUNT()
函数;从 C API 中,可以调用mysql_affected_rows()
函数。
关于未处理条件对程序参数的影响,见第15.6.7.8节,“条件处理和 OUT 或 INOUT 参数”。
要从存储过程中获取一个值,使用OUT
或INOUT
参数,通过用户变量将参数传递,然后在存储过程返回后检查变量的值。 (如果您正在从另一个存储过程或函数中调用该存储过程,可以将routine参数或本地routine变量作为IN
或INOUT
参数传递。) 对于INOUT
参数,需要在传递给存储过程前初始化其值。下面是一个存储过程,它有一个OUT
参数,该参数被设置为当前服务器版本,还有一个INOUT
参数,该参数由存储过程从其当前值加1:
DELIMITER //
CREATE PROCEDURE p (OUT ver_param VARCHAR(25), INOUT incr_param INT)
BEGIN
# Set value of OUT parameter
SELECT VERSION() INTO ver_param;
# Increment value of INOUT parameter
SET incr_param = incr_param + 1;
END //
DELIMITER ;
在调用存储过程前,初始化要传递的变量作为INOUT
参数。调用存储过程后,您可以看到这两个变量的值是否被设置或修改:
mysql> SET @increment = 10;
mysql> CALL p(@version, @increment);
mysql> SELECT @version, @increment;
+----------+------------+
| @version | @increment |
+----------+------------+
| 8.4.0 | 11 |
+----------+------------+
在使用CALL
语句,用于PREPARE
和EXECUTE
,可以使用占位符来代替IN
参数、OUT
和INOUT
参数。这些类型的参数可以按以下方式使用:
mysql> SET @increment = 10;
mysql> PREPARE s FROM 'CALL p(?, ?)';
mysql> EXECUTE s USING @version, @increment;
mysql> SELECT @version, @increment;
+----------+------------+
| @version | @increment |
+----------+------------+
| 8.4.0 | 11 |
+----------+------------+
要使用CALL
SQL 语句执行存储过程,生成结果集,需要启用 CLIENT_MULTI_RESULTS
标志。这是因为每个CALL
都会返回一个结果来表示调用状态,除非执行过程中的语句返回结果集。CLIENT_MULTI_RESULTS
也必须启用,如果使用CALL
执行包含预处理语句的存储过程。因为无法确定这些语句是否生成结果集,所以需要假设它们都生成结果集。
CLIENT_MULTI_RESULTS
可以在调用mysql_real_connect()
时启用,通过明确地传递 CLIENT_MULTI_RESULTS
标志或隐式地传递 CLIENT_MULTI_STATEMENTS
(也启用了 CLIENT_MULTI_RESULTS
)。CLIENT_MULTI_RESULTS
默认启用。
使用CALL
语句的结果,通过mysql_query()
或mysql_real_query()
执行,使用mysql_next_result()
循环来确定是否还有结果。例如,请参见多语句执行支持。
C语言程序可以使用预编译语句接口来执行CALL
语句,并访问OUT
和INOUT
参数。这是通过使用循环,调用mysql_stmt_next_result()
来确定是否还有结果的。例如,请参见预编译CALL语句支持。提供MySQL接口的语言可以使用预编译CALL
语句来直接获取OUT
和INOUT
过程参数。
存储程序中引用的对象的元数据变化将被检测到,并在下次执行时自动重新解析受影响的语句。更多信息,请参见第10.10.3节,“预准备语句和存储程序缓存”。