

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# CALL
<a name="r_CALL_procedure"></a>

运行存储过程。CALL 命令必须包括过程名称和输入参数值。您必须使用 CALL 语句调用存储过程。

**注意**  
CALL 不能成为任何常规查询的一部分。

## 语法
<a name="r_CALL_procedure-synopsis"></a>

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

## 参数
<a name="r_CALL_procedure-parameters"></a>

 *sp\$1name*   
要运行的过程的名称。

 *argument*   
输入参数的值。此参数也可以是函数名称，例如 `pg_last_query_id()`。您不能将查询用作 CALL 参数。

## 使用说明
<a name="r_CALL_procedure-usage-notes"></a>

Amazon Redshift 存储过程支持嵌套和递归调用，如下所述。此外，请确保您的驱动程序支持是最新的，如下所述

**Topics**
+ [嵌套调用](#r_CALL_procedure-nested-calls)
+ [驱动程序支持](#r_CALL_procedure-driver-support)

### 嵌套调用
<a name="r_CALL_procedure-nested-calls"></a>

Amazon Redshift 存储过程支持嵌套和递归调用。允许的最大嵌套级别数为 16。嵌套调用可以将业务逻辑封装到较小的过程中，这些过程可以由多个调用者共享。

如果调用了具有输出参数的嵌套过程，则该内部过程必须定义 INOUT 参数。在这种情况下，在非常量变量中传递该内部过程。不允许使用 OUT 参数。出现此问题的原因是需要一个变量来保存内部调用的输出。

内部过程和外部过程之间的关系记录在 `from_sp_call` 的 [SVL\$1STORED\$1PROC\$1CALL](r_SVL_STORED_PROC_CALL.md) 列中。

以下示例演示通过 INOUT 参数将变量传递给嵌套过程调用。

```
CREATE OR REPLACE PROCEDURE inner_proc(INOUT a int, b int, INOUT c int) LANGUAGE plpgsql
AS $$
BEGIN
  a := b * a;
  c := b * c;
END;
$$;

CREATE OR REPLACE PROCEDURE outer_proc(multiplier int) LANGUAGE plpgsql
AS $$
DECLARE
  x int := 3;
  y int := 4;
BEGIN
  DROP TABLE IF EXISTS test_tbl;
  CREATE TEMP TABLE test_tbl(a int, b varchar(256));
  CALL inner_proc(x, multiplier, y);
  insert into test_tbl values (x, y::varchar);
END;
$$;

CALL outer_proc(5);

SELECT * from test_tbl;
 a  | b
----+----
 15 | 20
(1 row)
```

### 驱动程序支持
<a name="r_CALL_procedure-driver-support"></a>

我们建议您将 Java 数据库连接 (JDBC) 和开放式数据库连接 (ODBC) 驱动程序升级到支持 Amazon Redshift 存储过程的最新版本。

如果客户端工具使用通过 CALL 语句传递给服务器的驱动程序 API 操作，则您可以使用现有驱动程序。输出参数（如果有）将作为包含一行的结果集返回。

最新版本的 Amazon Redshift JDBC 和 ODBC 驱动程序对存储过程发现提供元数据支持。这些最新版本对于自定义 Java 应用程序还支持 `CallableStatement`。有关驱动程序的更多信息，请参阅《Amazon Redshift 管理指南》**中的[使用 SQL 客户端工具连接到 Amazon Redshift 集群](https://docs.aws.amazon.com/redshift/latest/mgmt/connecting-to-cluster.html)。

以下示例说明如何对存储过程调用使用 JDBC 驱动程序的不同 API 操作。

```
void statement_example(Connection conn) throws SQLException {
  statement.execute("CALL sp_statement_example(1)");
}

void prepared_statement_example(Connection conn) throws SQLException {
  String sql = "CALL sp_prepared_statement_example(42, 84)";
  PreparedStatement pstmt = conn.prepareStatement(sql);
  pstmt.execute();
}

void callable_statement_example(Connection conn) throws SQLException {
  CallableStatement cstmt = conn.prepareCall("CALL sp_create_out_in(?,?)");
  cstmt.registerOutParameter(1, java.sql.Types.INTEGER);
  cstmt.setInt(2, 42);
  cstmt.executeQuery();
  Integer out_value = cstmt.getInt(1);
}
```

## 示例
<a name="r_CALL_procedure-examples"></a>

以下示例调用过程名称 `test_spl`。

```
call test_sp1(3,'book');
INFO:  Table "tmp_tbl" does not exist and will be skipped
INFO:  min_val = 3, f2 = book
```

以下示例调用过程名称 `test_spl2`。

```
call test_sp2(2,'2019');

         f2          | column2
---------------------+---------
 2019+2019+2019+2019 | 2
(1 row)
```