PostgreSQL 允许使用 位置 或 命名 表示形式来调用带有命名参数的函数。对于具有大量参数的函数,命名表示形式尤其有用,因为它使参数与实际参数之间的关联更加明确和可靠。在位置表示形式中,以其在函数声明中定义的相同顺序在函数调用中编写其参数值。在命名表示形式中,根据名称将参数与函数参数匹配,并且可以按任何顺序编写。对于每种表示形式,还要考虑在 第 10.3 节 中记录的函数参数类型的效果。
在任何一种表示形式中,在函数声明中给出默认值的都可以根本不需要在调用中写出。但在命名表示形式中,这特别有用,因为可以省略任何参数组合;而在位置表示形式中,只能从右向左省略参数。
PostgreSQL 还支持 混合 表示形式,它组合了位置和命名表示形式。在这种情况下,先写位置参数,然后出现命名参数。
以下示例将说明使用所有三种表示形式,使用以下函数定义
CREATE FUNCTION concat_lower_or_upper(a text, b text, uppercase boolean DEFAULT false) RETURNS text AS $$ SELECT CASE WHEN $3 THEN UPPER($1 || ' ' || $2) ELSE LOWER($1 || ' ' || $2) END; $$ LANGUAGE SQL IMMUTABLE STRICT;
函数 concat_lower_or_upper
具有两个必选参数,a
和 b
。此外,还有一个可选参数 uppercase
,其默认为 false
。a
和 b
输入将联接,并根据 uppercase
参数强制转换为大写或小写。此函数定义的其余详细信息在此并不重要(有关更多信息,请参见 第 36 章)。
位置表示形式是以传统机制将参数传递给 PostgreSQL 中的函数。一个示例是
SELECT concat_lower_or_upper('Hello', 'World', true); concat_lower_or_upper ----------------------- HELLO WORLD (1 row)
按顺序指定所有参数。结果为大写,因为 uppercase
指定为 true
。另一个示例是
SELECT concat_lower_or_upper('Hello', 'World'); concat_lower_or_upper ----------------------- hello world (1 row)
此处,省略了 uppercase
参数,因此它接收其默认值 false
,从而输出小写。在位置表示形式中,只要参数具有默认值,就可以从右到左省略参数。
在命名表示形式中,使用 =>
来指定每个参数的名称,以将它与参数表达式分开。例如
SELECT concat_lower_or_upper(a => 'Hello', b => 'World'); concat_lower_or_upper ----------------------- hello world (1 row)
同样,省略参数 uppercase
,则将隐式设置为 false
。使用命名表示法的一个好处是可以按任何顺序指定参数,例如
SELECT concat_lower_or_upper(a => 'Hello', b => 'World', uppercase => true); concat_lower_or_upper ----------------------- HELLO WORLD (1 row) SELECT concat_lower_or_upper(a => 'Hello', uppercase => true, b => 'World'); concat_lower_or_upper ----------------------- HELLO WORLD (1 row)
为了向后兼容,提供了基于 “:=” 的较旧语法
SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World'); concat_lower_or_upper ----------------------- HELLO WORLD (1 row)
混合表示法结合了位置表示法和命名表示法。但是,如前所述,命名参数不能在位置参数之前。例如
SELECT concat_lower_or_upper('Hello', 'World', uppercase => true); concat_lower_or_upper ----------------------- HELLO WORLD (1 row)
在上述查询中,参数 a
和 b
通过位置指定,而 uppercase
通过名称指定。在此示例中,这除了添加文档外,不会添加任何内容。在具有多个具有默认值的参数的更复杂的函数中,命名表示法或混合表示法可以节省大量的写入并降低出现错误的几率。
在调用聚合函数时,目前无法使用命名调用表示法和混合调用表示法(但在将聚合函数用作窗口函数时可以使用)。