↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 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 / 7.0 / 6.5 / 6.4
历史版本PostgreSQL 7.2 已于 2007 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

CREATE FUNCTION

CREATE FUNCTION — 定义一个新函数

大纲

CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] )
    RETURNS rettype
    AS 'definition'
    LANGUAGE langname
    [ WITH ( attribute [, ...] ) ]
CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] )
    RETURNS rettype
    AS 'obj_file', 'link_symbol'
    LANGUAGE langname
    [ WITH ( attribute [, ...] ) ]

描述

CREATE FUNCTION定义一个新函数。 CREATE OR REPLACE FUNCTION将创建一个新函数,或者替换现有定义。

参数

name

要创建的函数的名称。该名称不必唯一,因为函数可以重载,但同名函数必须有不同的参数类型。

argtype

函数参数的数据类型(如果有的话)。输入类型可以是基本类型或复合类型、 opaque,或者与现有列的类型相同。Opaque 表示函数接受非 SQL 类型的参数,例如char *。 用tablename.columnname%TYPE的形式来指示一个列的类型; 有时使用这种写法可以帮助让函数独立于表定义的变化。

rettype

返回数据类型。输出类型可以指定为基本类型、复合类型、setof 类型、opaque,或者与现有列的类型相同。 setof 修饰符表示该函数将返回一组结果项,而不是单个项。声明返回类型为 opaque的函数不返回值。这类函数不能被直接调用;触发器函数利用了这个特性。

definition

定义函数的字符串;其含义取决于语言。它可以是内部函数名、对象文件的路径、SQL 查询,或者过程语言中的文本。

obj_file, link_symbol

当 C 语言源代码中的函数名与 SQL 函数名不同时,动态链接的 C 语言函数使用这种形式的AS子句。字符串obj_file是包含可动态载入对象的文件名,而 link_symbol是对象的链接符号,也就是 C 语言源代码中函数的名称。

langname

可以是SQL、C、 internal,或者plname,其中plname是一种已创建过程语言的名称。详见 CREATE LANGUAGE。 为了向后兼容,该名称可以用单引号包围。

attribute

关于函数的一条可选信息,用于优化。详见下文。

创建该函数的用户将成为该函数的拥有者。

下列属性可以出现在 WITH 子句中:

iscachable

Iscachable表示该函数在给定相同参数值时总是返回相同结果(也就是说,它不做数据库查找,也不使用不直接出现在其参数列表中的信息)。优化器利用iscachable来判断预计算该函数的一次调用是否安全。

isstrict

isstrict表示只要任一参数为 NULL,函数就总是返回 NULL。如果指定了这个属性,当存在 NULL 参数时函数不会被执行;而是自动假定结果为 NULL。当未指定isstrict时,函数将针对 NULL 输入被调用。此时如有必要,由函数作者负责检查 NULL 并做出适当响应。

注意

关于编写外部函数的更多信息,请参考 PostgreSQL 程序员指南 中关于通过函数扩展 PostgreSQL主题的章节。

输入参数和返回值允许使用完整的SQL类型语法。但是,类型规范的某些细节(例如 numeric类型的精度字段)由底层函数实现负责,CREATE FUNCTION命令会静默地忽略它们(即不识别也不强制执行)。

PostgreSQL允许函数重载; 也就是说,只要几个不同函数的参数类型不同,它们就可以使用同一个名称。但对 internal 和 C 语言函数,必须谨慎使用这一设施。

两个internal 函数如果 C 名相同,会在链接时引发错误。要解决这个问题,可以给它们起不同的 C 名(例如,把参数类型用作 C 名的一部分),然后在CREATE FUNCTION的 AS 子句中指定这些名字。 如果 AS 子句留空,则CREATE FUNCTION 假定函数的 C 名与 SQL 名相同。

类似地,当用多个 C 语言函数重载 SQL 函数名时,给函数的每个 C 语言实例起一个不同的名字,然后在 CREATE FUNCTION语法中使用AS子句的另一种形式,为每个重载的 SQL 函数选择合适的 C 语言实现。

当多次CREATE FUNCTION调用引用同一个对象文件时,该文件只会被装载一次。要卸载并重新装载该文件(也许是在开发期间),可以使用LOAD命令。

使用DROP FUNCTION 删除用户定义的函数。

要更新现有函数的定义,可以使用CREATE OR REPLACE FUNCTION。注意,不能用这种方式更改函数的名称或者参数类型(如果尝试这样做,实际上就会创建一个新的不同函数)。此外,CREATE OR REPLACE FUNCTION也不允许更改现有函数的返回类型。要做到这一点,必须删除该函数并重新创建。

如果删除函数后再重新创建,新函数就不再是旧函数的同一实体;你将破坏引用旧函数的现有规则、视图、触发器等。使用CREATE OR REPLACE FUNCTION可以在不破坏引用该函数的对象的情况下更改函数定义。

示例

创建一个简单的 SQL 函数:

CREATE FUNCTION one() RETURNS integer
    AS 'SELECT 1 AS RESULT;'
    LANGUAGE SQL;

SELECT one() AS answer;
 answer 
--------
      1

下一个示例通过调用一个用户创建的名为funcs.so的共享库(扩展名可能因平台而异)中的例程来创建一个 C 函数。共享库文件会在服务器的动态库搜索路径中寻找。这个特定的例程计算一个校验位,如果函数参数中的校验位正确就返回 TRUE。它用于 CHECK 约束中。

CREATE FUNCTION ean_checkdigit(char, char) RETURNS boolean
    AS 'funcs' LANGUAGE C;
    
CREATE TABLE product (
    id        char(8) PRIMARY KEY,
    eanprefix char(8) CHECK (eanprefix ~ '[0-9]{2}-[0-9]{5}')
                      REFERENCES brandname(ean_prefix),
    eancode   char(6) CHECK (eancode ~ '[0-9]{6}'),
    CONSTRAINT ean    CHECK (ean_checkdigit(eanprefix, eancode))
);

这个示例创建一个在用户定义类型 complex 与内部类型 point 之间做类型转换的函数。该函数由一个从 C 源码编译出的动态载入对象实现(我们展示指定共享对象文件确切路径名这种现已废弃的替代方式)。为了让PostgreSQL自动找到类型转换函数,SQL 函数必须与返回类型同名,因此重载不可避免。在 SQL 定义中使用AS子句的第二种形式来重载函数名:

CREATE FUNCTION point(complex) RETURNS point
    AS '/home/bernie/pgsql/lib/complex.so', 'complex_to_point'
    LANGUAGE C;

该函数的 C 声明可以是:

Point * complex_to_point (Complex *z)
{
        Point *p;

        p = (Point *) palloc(sizeof(Point));
        p->x = z->x;
        p->y = z->y;
                
        return p;
}

兼容性

CREATE FUNCTION命令在 SQL99 中定义。 PostgreSQL的版本与之类似但 不兼容。属性不可移植,各种可用语言也一样。

另见

DROP FUNCTION , LOAD, PostgreSQL 程序员指南

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。