金仓数据库KingbaseES PLSQL中的可变参数—VARIADIC
关键字:
KingbaseES、可变参数、VARIADIC;人大金仓;KingbaseES
在创建一个具有参数的子程序(函数或存储过程)时,在每个形式参数的声明中,需要指定参数的名称、数据类型以及可选的模式。在KingbaseES PLSQL中,主要提供了以下四种参数模式:IN(默认值)、OUT、INOUT和VARIADIC。本文将介绍如何在KingbaseES中声明“VARIADIC”参数以及它的具体用法。
VARIADIC的概念
VARIADIC是KingbaseES中一种特殊的参数模式,被标记为“VARIADIC”的参数是输入参数,其表示一个子程序可以接收可变数量的参数,这些参数将被作为一个数组传递给函数。使用“VARIADIC”参数的好处在于函数可以处理多个参数,而无需在函数定义是明确参数的数量。
VARIADIC的用法
首先,声明一个包含“VARIADIC”参数的子程序, VARIADIC参数的声明语法如下:
VARIADIC [ argname ] argtype
其中,argname为一个可选项,表示参数的名称,当其缺省时,用 $i表示(i为参数所在的位置)。若子程序不包含OUT参数,则只能将其的最后一个形式参数标记为VARIADIC模式。此外,VARIADIC参数只能被声明为数组类型(即argtype只能为一个数组类型)。下面的示例中声明了一个包含“VARIADIC”参数的函数:
\set SQLTERM /
CREATE OR REPLACE FUNCTION func (num number, VARIADIC arr number[] )
RETURN number AS
v_sum NUMBER := 0;
i number;
BEGIN
RAISE NOTICE 'num = %', $1; --输出第一个位置的参数,即num
FOREACH i IN ARRAY arr LOOP --循环遍历数组arr中的每一个元素,并求其总和
v_sum := v_sum + i;
END LOOP;
RETURN v_sum;
END;
/
随后,调用包含VARIADIC参数的函数:
SELECT func(1,1,2,3,4,5); --返回15
/
SELECT func(2,15,25,35,45,55); --返回175
/
从以上实例中可以看到,VARIADIC为第二个形式参数,因此从第二个位置开始的所有实参都会被收集成一个数组,对函数func的调用就相当于在做以下工作:
select func(1, ARRAY[1,2,3,4,5]); --这只是一个解释说明,实际调用以示例中的为准
select func(2, ARRAY[15,25,35,45,55]);
此外,KingbaseES还提供了伪类型anyarray,用于表示一个函数可以接收任意数组数据类型。因此,声明子程序的参数时,如果使用anyarray代替具体类型的数据,子程序就可以接收任意类型的数组了。示例如下:
\set SQLTERM /
CREATE OR REPLACE PROCEDURE proc (variadic arr anyarray) AS
i TEXT;
BEGIN
FOREACH i IN ARRAY arr LOOP
RAISE NOTICE '%', i;
END LOOP;
END;
/
DECLARE
i varchar2 := 'a';
j varchar2 := 'b';
k varchar2 := 'c';
BEGIN
RAISE NOTICE '---1---';
proc(1,2,3); --传入ARRAY [1,2,3]
RAISE NOTICE '---2---';
proc(i, j, k); ---传入ARRAY ['a', 'b', 'c']
END;
/
使用VARIADIC的注意事项
- VARIADIC参数需要至少匹配一个实参
对于上述示例,以下调用将会报错:
SELECT func (1);
CALL proc();
如果在调用中需要将空数组传递给VARIADIC参数,以下为唯一实现方式:
SELECT func(1, VARIADIC ARRAY[] :: number[]);
CALL proc (VARIADIC ARRAY[] :: number[]);
- 使用命名参数法传参
不能在调用包含VARIADIC参数的子程序时,通过命名表示法来传参,除非指定了VARIADIC参数之外,示例如下:
SELECT func (num => 1, VARIADIC arr => ARRAY[1,2,3,4,5] );
CALL proc (VARIADIC arr => ARRAY[1,2,3] );
应用场景
- 需要处理可变数量的参数:
在某些场景下,您可能需要一个子程序,来处理参数数量不确定的情况(例如:列如对一组数据求和、求平均值等)。此时,可以定义包含“VARIADIC”参数的子程序,来接受任意数量的参数作为输入。
2. 避免子程序重载:
子程序重载主要包括以下两个条件:子程序名相同、参数个数不同或参数类型不同。通过创建多个同名子程序,可以在调用子程序时根据参数的数量或类型来匹配最合适的子程序。然而,使用包含“VARIADIC”参数的子程序,可以接收任意数量的参数,从而无需再创建多个重载子程序,有效的避免了子程序重载带来的复杂性。
总结
VARIADIC参数模式为处理可变数量的参数提供了更大的灵活性。在定义子程序时,声明VARIADIC模式的参数,子程序就可以接收可变数量的参数了。