Amazon Redshift
数据库开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

CALL

运行存储过程。CALL 命令必须包括过程名称和输入参数值。您必须使用 CALL 语句调用存储过程。CALL 不能成为任何常规查询的一部分。

语法

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

参数

sp_name

要运行的过程的名称。

argument

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

使用说明

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

嵌套调用

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

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

内部过程和外部过程之间的关系记录在 SVL_STORED_PROC_CALLfrom_sp_call 列中。

以下示例演示通过 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)

驱动程序支持

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

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

最新版本的 Amazon Redshift JDBC 和 ODBC 驱动程序对存储过程发现提供元数据支持。这些最新版本对于自定义 Java 应用程序还支持 CallableStatement。有关驱动程序的更多信息,请参阅 Amazon Redshift Cluster Management Guide 中的使用 SQL 客户端工具连接到 Amazon Redshift 集群

重要

目前,您不能使用 JDBC 或 ODBC 驱动程序在存储过程中使用 refcursor 数据类型。

以下示例说明如何对存储过程调用使用 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); }

示例

以下示例调用过程名称 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)

本页内容: