2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:开发版
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

36.6. 函数重载 #

只要所接受的参数不同,就可以定义多个具有相同 SQL 名称的函数。换句话说,函数名称可以被重载。无论是否使用,此功能在某些用户不信任其他用户的数据库中调用函数时都包含安全预防措施;请参阅第 10.3 节。执行查询时,服务器将根据提供的数据类型和参数数量确定要调用的函数。重载也可用于模拟具有可变数量参数的函数,最多可达有限的最大数量。

创建重载函数族时,应注意避免创建歧义。例如,给定以下函数:

CREATE FUNCTION test(int, real) RETURNS ...
CREATE FUNCTION test(smallint, double precision) RETURNS ...

对于一些简单的输入(如test(1, 1.5)),目前尚不清楚将调用哪个函数。当前实现的解析规则在第 10 章中进行了描述,但设计一个微妙地依赖于此行为的系统是不明智的。

对于接受复合类型单个参数的函数,通常不应将其名称与该类型的任何属性(字段)相同。请记住,attribute(table) 被认为等效于 table.attribute。如果在复合类型上的函数和复合类型的属性之间存在歧义,则始终使用属性。可以通过限定函数名称的模式来覆盖该选择(即 schema.func(table)),但这最好通过不选择冲突的名称来避免此问题。

另一个可能的冲突是在可变参数函数和非可变参数函数之间。例如,可以同时创建 foo(numeric)foo(VARIADIC numeric[])。在这种情况下,不清楚哪个函数应该与提供单个数值参数的调用匹配,例如 foo(10.1)。规则是使用搜索路径中较早出现的函数,或者如果两个函数位于同一个模式中,则首选非可变参数函数。

在重载 C 语言函数时,还有一个附加约束:函数族中每个函数的 C 名称必须不同于所有其他函数(无论是内部函数还是动态加载函数)的 C 名称。如果违反此规则,则行为不可移植。您可能会收到运行时链接器错误,或者将调用其中一个函数(通常是内部函数)。SQL CREATE FUNCTION 命令的 AS 子句的替代形式将 SQL 函数名称与 C 源代码中的函数名称解耦。例如:

CREATE FUNCTION test(int) RETURNS int
    AS 'filename', 'test_1arg'
    LANGUAGE C;
CREATE FUNCTION test(int, int) RETURNS int
    AS 'filename', 'test_2arg'
    LANGUAGE C;

此处 C 函数的名称反映了许多可能的约定之一。

提交更正

如果您在文档中看到任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用此表单报告文档问题。