可以用同样的 SQL 名称定义多于一个函数,只要它们的参数不同即可。 换句话说,函数名可以被重载。不管你是否使用它,这种能力都要求在某些用户不信任其他用户的数据中调用函数时做一些预防措施,见Section 10.3。当一个查询 被执行时,服务器将从数据类型和所提供的参数个数来决定要调用哪个 函数。重载也可用来模拟具有可变参数个数(最大个数有限)的函数。
在创建一个重载函数家族时,应该小心不要创建歧义。例如,给定函数:
CREATE FUNCTION test(int, real) RETURNS ... CREATE FUNCTION test(smallint, double precision) RETURNS ...
对于test(1, 1.5)这样的输入就无法立刻清楚地知道 应该调用哪个函数。当前实现的解决规则在Chapter 10 中有描述,但是设计一个依赖于这种行为的系统是不明智的。
具有单个复合类型参数的函数,通常不应与该类型的任何属性(字段)同名。 回想一下,被视为等价于 attribute(table)。 如果在“作用于复合类型的函数”与“复合类型的属性”之间出现歧义,系统总会优先选择属性。 可以通过给函数名加上模式限定(即 table.attribute) 来覆盖这一选择,但更好的做法仍然是避免使用会冲突的名字。schema.func(table)
另一类可能的冲突发生在 variadic 函数和非 variadic 函数之间。例如,可以同时创建 foo(numeric) 和 foo(VARIADIC numeric[])。 这时,对于只提供一个 numeric 参数的调用(例如 foo(10.1)),就不清楚该匹配哪个函数。 规则是:优先使用在搜索路径中出现较早的那个函数;如果两者位于同一模式中,则优先使用非 variadic 函数。
在重载 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 函数名称反映了很多种可能的习惯之一。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。