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

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

第 37 章 PL/Perl - Perl 过程语言

PL/Perl 是一种可加载的过程语言,可以用 Perl 编程语言编写 PostgreSQL 函数。

要在某个特定数据库中安装 PL/Perl,使用 createlang plperl dbname。

提示

如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。

注意

使用源码包的用户必须在安装过程中专门启用 PL/Perl 的构建(更多信息见 第 14 章)。使用二进制包的用户可能会在单独的 子包中找到 PL/Perl。

37.1. PL/Perl 函数和参数 #

要用 PL/Perl 语言创建一个函数,可使用标准语法:

CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$
    # PL/Perl 函数体
$$ LANGUAGE plperl;

函数的主体就是普通的 Perl 代码。

CREATE FUNCTION 命令的语法要求函数体写成一个 字符串常量。通常对该字符串常量使用美元引用(见 第 4.1.2.2 节)最方便。如果选择使用常规的 单引号字符串常量语法,就必须对函数体中用到的单引号 (')和反斜线(\)进行转义, 通常是把它们写成双份(见 第 4.1.2.1 节)。

参数和结果的处理与其他 Perl 子程序一样:参数通过 @_ 传入,结果值通过 return 返回,或者作为函数中最后一个被求值的表达式返回。

例如,一个返回两个整数值中较大值的函数可以定义为:

CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
    if ($_[0] > $_[1]) { return $_[0]; }
    return $_[1];
$$ LANGUAGE plperl;

如果一个 SQL 空值被传给一个函数,在 Perl 中该参数值将呈现为“未定义”。上述函数定义对于 空值输入的行为并不理想(实际上,它会把它们当作零)。我们可以在函数 定义中添加 STRICT,让 PostgreSQL 采取更合理的做法:如果传入空值, 函数将根本不会被调用,而是自动返回空值结果。另一种方式是在函数体中 检查未定义输入。例如,假设我们希望在 perl_max 的两个参数中一个为空值、另一个非空值时,返回非空值参数而不是空值:

CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
    my ($a,$b) = @_;
    if (! defined $a) {
        if (! defined $b) { return undef; }
        return $b;
    }
    if (! defined $b) { return $a; }
    if ($a > $b) { return $a; }
    return $b;
$$ LANGUAGE plperl;

如上所示,要从 PL/Perl 函数返回 SQL 空值,就返回一个未定义值。 无论函数是否为严格函数,都可以这样做。

复合类型参数被作为哈希的引用传递给函数。哈希的键是复合类型的 属性名。这里是一个示例:

CREATE TABLE employee (
    name text,
    basesalary integer,
    bonus integer
);

CREATE FUNCTION empcomp(employee) RETURNS integer AS $$
    my ($emp) = @_;
    return $emp->{basesalary} + $emp->{bonus};
$$ LANGUAGE plperl;

SELECT name, empcomp(employee.*) FROM employee;

PL/Perl 函数也可以用相同的方法返回复合类型:返回一个具有所需属性的 哈希的引用。例如:

CREATE TYPE testrowperl AS (f1 integer, f2 text, f3 text);

CREATE OR REPLACE FUNCTION perl_row() RETURNS testrowperl AS $$
    return {f2 => 'hello', f1 => 1, f3 => 'world'};
$$ LANGUAGE plperl;

SELECT * FROM perl_row();

在声明的结果数据类型中,凡是哈希中未出现的列都将作为空值返回。

PL/Perl 函数也可以返回标量类型或复合类型的集合。为此,可以返回一个数组引用,其中对两种情况分别包含标量或哈希引用。下面是几个简单示例:

CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
return [0..$_[0]];
$$ LANGUAGE plperl;

SELECT * FROM perl_set_int(5);


CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
    return [
        { f1 => 1, f2 => 'Hello', f3 => 'World' },
        { f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' },
        { f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' }
    ];
$$  LANGUAGE plperl;

SELECT * FROM perl_set();

注意,采用这种方法时,Perl 必须在内存中构建整个数组;因此该技术无法扩展到非常大的结果集。

PL/Perl 目前对域类型没有完整支持:它把域同其底层 标量类型一样对待。这意味着与域关联的约束不会被强制执行。这对函数 参数来说不是问题,但如果你把一个 PL/Perl 函数声明 为返回域类型,就会存在隐患。

提交更正

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