调用存储过程¶
可以使用 SQL CALL 命令调用存储过程。
为了让用户调用存储过程,用户的角色必须具有对存储过程的 USAGE 权限。
具有调用存储过程的权限之后,就可以使用 CALL 语句来调用存储过程。
备注
要创建和调用匿名过程,请使用 CALL(使用匿名过程)。创建和调用匿名过程不需要具有 CREATE PROCEDURE 架构权限的角色。
指定实参¶
如果存储过程具有实参,则可以按名称或位置指定这些实参。
例如,以下存储过程接受三个实参:
CREATE OR REPLACE PROCEDURE sp_concatenate_strings(
first_arg VARCHAR,
second_arg VARCHAR,
third_arg VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
BEGIN
RETURN first_arg || second_arg || third_arg;
END;
$$;
调用过程时,可以按名称指定实参:
CALL sp_concatenate_strings(
first_arg => 'one',
second_arg => 'two',
third_arg => 'three');
+------------------------+
| SP_CONCATENATE_STRINGS |
|------------------------|
| onetwothree |
+------------------------+
如果按名称指定实参,则不需要按任何特定顺序指定实参:
CALL sp_concatenate_strings(
third_arg => 'three',
first_arg => 'one',
second_arg => 'two');
+------------------------+
| SP_CONCATENATE_STRINGS |
|------------------------|
| onetwothree |
+------------------------+
您还可以按位置指定实参:
CALL sp_concatenate_strings(
'one',
'two',
'three');
+------------------------+
| SP_CONCATENATE_STRINGS |
|------------------------|
| onetwothree |
+------------------------+
请注意以下事项:
必须按名称或位置指定所有实参。不能按名称指定某些实参,也不能按位置指定其他实参。
按名称指定实参时,不能在实参名称前后使用双引号。
如果两个函数或两个过程的名称相同但实参类型不同,那么在实参名称不同的情况下,可以使用实参名称来指定要执行的函数或过程。请参阅:ref:label-procedure_function_name_overloading。
指定可选实参¶
如果存储过程具有:ref:可选实参<label-procedure_function_arguments_optional>,则可以在调用中省略可选实参。每个可选实参都有一个默认值,当省略该实参时将使用该默认值。
例如,以下存储过程具有一个必填实参和两个可选实参。每个可选实参都有一个默认值。
CREATE OR REPLACE PROCEDURE build_string_proc(
word VARCHAR,
prefix VARCHAR DEFAULT 'pre-',
suffix VARCHAR DEFAULT '-post'
)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
BEGIN
RETURN prefix || word || suffix;
END;
$$
;
您可以在调用中省略任何可选实参。省略实参时,将使用该实参的默认值。
CALL build_string_proc('hello');
+-------------------+
| BUILD_STRING_PROC |
|-------------------|
| pre-hello-post |
+-------------------+
CALL build_string_proc('hello', 'before-');
+-------------------+
| BUILD_STRING_PROC |
|-------------------|
| before-hello-post |
+-------------------+
如果需要省略可选实参,并在签名中指定出现在被省略实参之后的另一个可选实参,请使用命名实参,而不是位置实参。
例如,假设您要省略 prefix
实参,并指定 suffix
实参。suffix
实参显示在签名中的 prefix
之后,因此必须按名称指定实参:
CALL build_string_proc(word => 'hello', suffix => '-after');
+-------------------+
| BUILD_STRING_PROC |
|-------------------|
| pre-hello-after |
+-------------------+
示例¶
若要执行存储过程,请使用 CALL 语句。例如:
call stproc1(5.14::FLOAT);
存储过程的每个实参都可以是通用表达式:
CALL stproc1(2 * 5.14::FLOAT);
实参可以是子查询:
CALL stproc1(SELECT COUNT(*) FROM stproc_test_table1);
每个 CALL 语句只能调用一个存储过程。例如,以下语句失败:
call proc1(1), proc2(2); -- Not allowed
此外,不能将存储过程 CALL 用作表达式的一部分。例如,以下所有语句都失败:
call proc1(1) + proc1(2); -- Not allowed
call proc1(1) + 1; -- Not allowed
call proc1(proc2(x)); -- Not allowed
select * from (call proc1(1)); -- Not allowed
但是,在存储过程中,存储过程可以调用另一个存储过程,也可以以递归方式调用自身。
小心
嵌套调用可能会超过允许的最大堆栈深度,因此在嵌套调用时要小心,尤其是在使用递归时。