### 13.2.1 CALL 语句

[](<>)

```
CALL sp_name([parameter[,...]])
CALL sp_name[()]
```

这[`称呼`](call.html)语句调用之前定义的存储过程[`创建过程`](create-procedure.html).

可以不带括号调用不带参数的存储过程。那是，`调用 p()`和`呼叫 p`是等价的。

[`称呼`](call.html)可以使用声明为的参数将值传回给它的调用者`出去`要么`进出`参数。当过程返回时，客户端程序还可以获得在例程中执行的最终语句受影响的行数： 在 SQL 级别，调用[`ROW_COUNT()`](information-functions.html#function_row-count)功能;从 C API，调用[`mysql_affected_rows()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-affected-rows.html)功能。

有关未处理条件对过程参数的影响的信息，请参阅[第 13.6.7.8 节，“条件处理和 OUT 或 INOUT 参数”](conditions-and-parameters.html).

使用`出去`要么`进出`参数，通过用户变量的方式传递参数，然后在过程返回后检查变量的值。（如果您从另一个存储过程或函数中调用该过程，您还可以将例程参数或局部例程变量作为`在`要么`进出`参数。）对于一个`进出`参数，在将其传递给过程之前初始化其值。下面的过程有一个`出去`过程设置为当前服务器版本的参数，以及`进出`过程从其当前值加一的值：

```
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;
```

在调用过程之前，将要传递的变量初始化为`进出`范围。调用该过程后，可以看到两个变量的值被设置或修改：

```
mysql> SET @increment = 10;
mysql> CALL p(@version, @increment);
mysql> SELECT @version, @increment;
+--------------------+------------+
| @version           | @increment |
+--------------------+------------+
| 8.0.3-rc-debug-log |         11 |
+--------------------+------------+
```

在准备中[`称呼`](call.html)使用的语句[`准备`](prepare.html)和[`执行`](execute.html), 占位符可用于`在`参数，`出去`， 和`进出`参数。这些类型的参数可以按如下方式使用：

```
mysql> SET @increment = 10;
mysql> PREPARE s FROM 'CALL p(?, ?)';
mysql> EXECUTE s USING @version, @increment;
mysql> SELECT @version, @increment;
+--------------------+------------+
| @version           | @increment |
+--------------------+------------+
| 8.0.3-rc-debug-log |         11 |
+--------------------+------------+
```

编写使用[`称呼`](call.html)SQL 语句来执行产生结果集的存储过程，`CLIENT_MULTI_RESULTS`标志必须启用。这是因为每个[`称呼`](call.html)除了过程中执行的语句可能返回的任何结果集之外，还返回一个结果以指示调用状态。`CLIENT_MULTI_RESULTS`如果还必须启用[`称呼`](call.html)用于执行任何包含准备好的语句的存储过程。无法确定加载此类过程时这些语句是否产生结果集，因此有必要假设它们这样做。

`CLIENT_MULTI_RESULTS`打电话时可以启用[`mysql_real_connect()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-real-connect.html)，或者通过明确地传递`CLIENT_MULTI_RESULTS`标记自身，或通过传递`CLIENT_MULTI_STATEMENTS`（这也使`CLIENT_MULTI_RESULTS`）。`CLIENT_MULTI_RESULTS`默认启用。

处理一个结果[`称呼`](call.html)使用执行的语句[`mysql_query()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-query.html)要么[`mysql_real_query()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-real-query.html), 使用循环调用[`mysql_next_result()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-next-result.html)以确定是否有更多结果。例如，请参见[多语句执行支持](https://dev.mysql.com/doc/c-api/8.0/en/c-api-multiple-queries.html).

C程序可以使用prepared-statement接口来执行[`称呼`](call.html)声明和访问`出去`和`进出`参数。这是通过处理的结果来完成的[`称呼`](call.html)使用循环的语句调用[`mysql_stmt_next_result()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-stmt-next-result.html)以确定是否有更多结果。例如，请参阅[准备好的 CALL 语句支持](https://dev.mysql.com/doc/c-api/8.0/en/c-api-prepared-call-statements.html).提供 MySQL 接口的语言可以使用准备好的[`称呼`](call.html)直接检索的语句`出去`和`进出`程序参数。

检测到存储程序引用的对象的元数据更改，并在下次执行程序时自动重新解析受影响的语句。有关详细信息，请参阅[第 8.10.3 节，“准备语句和存储程序的缓存”](statement-caching.html).
