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节,“预准备语句和存储程序缓存”。