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

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.3 已于 2007 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

CREATE FUNCTION

CREATE FUNCTION — 定义一个新函数

大纲

CREATE [ OR REPLACE ] FUNCTION name ( [ argtype [, ...] ] )
    RETURNS rettype
  { LANGUAGE langname
    | IMMUTABLE | STABLE | VOLATILE
    | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
    | [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
    | AS 'definition'
    | AS 'obj_file', 'link_symbol'
  } ...
    [ WITH ( attribute [, ...] ) ]

描述

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

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

参数

name

要创建的函数的名称。如果包含模式名,则函数将在指定的模式中创建。否则将在当前模式(搜索路径最前面的那个;见CURRENT_SCHEMA())中创建。新函数的名称不能与同一模式中具有相同参数类型的任何现有函数匹配。然而,不同参数类型的函数可以共享一个名称(这称为重载)。

argtype

函数参数的数据类型(如果有的话)。输入类型可以是基本类型、复合类型或域类型,也可以与现有列的类型相同。 引用一个列的类型时写作tablename.columnname%TYPE; 有时使用这种写法可以帮助让函数独立于表定义的变化。 取决于实现语言,也可能允许指定cstring之类的“伪类型”。 伪类型表示实际参数类型要么没有完整指定,要么在普通 SQL 数据类型的范围之外。

rettype

返回数据类型。返回类型可以指定为基本类型、复合类型或域类型,也可以与现有列的类型相同。 取决于实现语言,也可能允许指定cstring之类的“伪类型”。 setof 修饰符表示该函数将返回一组结果项,而不是单个项。

langname

函数实现所用的语言名称。可以是SQL、C、 internal,或者一种用户定义的过程语言的名称。 (另见createlang。)为了向后兼容,该名称可以用单引号包围。

IMMUTABLE
STABLE
VOLATILE

这些属性告知系统,出于运行时优化的目的,用单次求值替换对函数的多次求值是否安全。 最多只能指定其中之一。如果没有出现这些选项, 默认假定是VOLATILE。

IMMUTABLE表示该函数在给定相同参数值时总是返回相同结果;也就是说,它不做数据库查找,也不使用不直接出现在其参数列表中的信息。如果给出了这个选项,任何用全常量参数对该函数的调用都可以立即替换为函数值。

STABLE表示在一次表扫描中,该函数对相同参数值会一致地返回相同结果,但其结果可能跨 SQL 语句变化。对于结果依赖数据库查找、参数变量(例如当前时区)等的函数,这是合适的选择。还要注意,CURRENT_TIMESTAMP函数族属于稳定(stable),因为它们的值在一个事务内不会改变。

VOLATILE表示即使在一次表扫描中函数值也可能改变,因此无法做任何优化。相对较少的数据库函数在这个意义上是易变(volatile)的; 一些例子是random()、currval()、 timeofday()。注意,任何有副作用的函数都必须归类为 volatile,即使其结果相当可预测,以防止调用被优化掉;一个例子是 setval()。

CALLED ON NULL INPUT
RETURNS NULL ON NULL INPUT
STRICT

CALLED ON NULL INPUT(默认值)表示当某些参数为 NULL 时,函数仍会被正常调用。此时如有必要,由函数作者负责检查空值并做出适当响应。

RETURNS NULL ON NULL INPUT或 STRICT表示只要任一参数为 NULL,函数就总是返回 NULL。如果指定了这个选项,当存在 NULL 参数时函数不会被执行;而是自动假定结果为 NULL。

[EXTERNAL] SECURITY INVOKER
[EXTERNAL] SECURITY DEFINER

SECURITY INVOKER表示函数将以调用它的用户的权限执行。 这是默认值。SECURITY DEFINER 指定函数将以创建它的用户的权限执行。

关键字EXTERNAL是为了 SQL 兼容性而存在的,但它是可选的,因为与 SQL 中不同,这个特性并不只适用于外部函数。

definition

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

obj_file, link_symbol

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

attribute

指定函数可选信息的传统方式。这里可以出现下列属性:

isStrict

等价于STRICT或RETURNS NULL ON NULL INPUT

isCachable

isCachable是IMMUTABLE的已废弃等价物;出于向后兼容的原因它仍被接受。

属性名不区分大小写。

注意

关于编写外部函数的更多信息,请参考 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可以在不破坏引用该函数的对象的情况下更改函数定义。

要能够定义函数,用户必须具有该语言上的USAGE权限。

默认情况下,只有函数的拥有者(创建者)有权执行它。其他用户必须被授予该函数上的EXECUTE权限才能使用它。

示例

创建一个简单的 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 STRICT;

该函数的 C 声明可以是:

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

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

注意该函数被标记为“strict”;这使我们可以跳过函数体中的 NULL 输入检查。

安全地编写SECURITY DEFINER函数

由于SECURITY DEFINER函数以创建它的用户的权限执行,需要小心确保函数不被滥用。出于安全考虑,应把search_path设置为排除任何可被不受信任用户写入的模式。这可以防止恶意用户创建遮蔽函数所用对象的对象。在这方面特别重要的是临时表模式,它默认最先被搜索,而且通常任何人都可以写。可以通过强制临时模式最后被搜索来获得安全的安排。为此,把pg_temp写成search_path中的最后一项。下面的函数展示了安全用法:

CREATE FUNCTION check_password(TEXT, TEXT)
RETURNS BOOLEAN AS '
DECLARE passed BOOLEAN;
        old_path TEXT;
BEGIN
        -- Save old search_path; notice we must qualify current_setting
        -- to ensure we invoke the right function
        old_path := pg_catalog.current_setting(''search_path'');

        -- Set a secure search_path: trusted schemas, then ''pg_temp''.
        -- We set is_local = true so that the old value will be restored
        -- in event of an error before we reach the function end.
        PERFORM pg_catalog.set_config(''search_path'', ''admin, pg_temp'', true);

        -- Do whatever secure work we came for.
        SELECT  (pwd = $2) INTO passed
        FROM    pwds
        WHERE   username = $1;

        -- Restore caller''s search_path
        PERFORM pg_catalog.set_config(''search_path'', old_path, true);

        RETURN passed;
END;
' LANGUAGE plpgsql SECURITY DEFINER;

兼容性

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

另见

DROP FUNCTION, GRANT, LOAD, REVOKE, createlang, PostgreSQL 程序员指南

提交更正

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