Chapter 21. PL/Perl - Perl 过程语言

Table of Contents
21.1. PL/Perl 函数和参数
21.2. PL/Perl 里的数据值
21.3. 从 PL/Perl 里访问数据库
21.4. 可信的和不可信的 PL/Perl
21.5. 缺少的特性

PL/Perl 是一种可装载的过程语言,通过它我们可以 用 Perl 编程语言写 PostgreSQL 函数.

要在特定数据库里安装 PL/Perl,使用 createlang plperl dbname.

窍门: 如果某种编程语言安装到乐 template1,那么所有随后创建 的数据库都会自动安装这种语言。

注意: 使用源码包的用户必须在安装过程中特别打开 PL/Perl 的制作 (请参考安装指导获取更多信息)。二进制包的用户可能会在 一些独立的子包中找到 PL/Perl。

21.1. PL/Perl 函数和参数

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

CREATE FUNCTION funcname (argument-types) RETURNS return-type AS '
    # PL/Perl function body
' LANGUAGE plperl;

函数体是普通的 Perl 代码。

参数和结果都是和任何其它 Perl 子过程 里那样处理的∶参数是放在 @_ 里传递的, 结果值是用 return 返回或者作为函数中最后计算的表达式 的值返回.比如,一个返回两个整数中较大值的函数可以这么写∶

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

如果给函数传递一个 SQL null 那么其参数值将以 Perl 中 "undefined" 的形式出现.上面的函数定义在输入为 null 时的行为不是很正常(实际上, 它将表现得好像它们都是零一样).我们可以给函数定义增加 STRICT,让 PostgreSQL 做一些更合理的事情∶如果传递进来一个 NULL,那么该函数则根本不会被 调用,而只是自动返回一个 NULL结果.另外,我们可以在函数体里检查 未定义(undefined)的输入.比如,假设我们想收到一个 null 和一个非 null 参数的 perl_max 返回非 null 的参数,而不是 null 值∶

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 null,我们可以返回一个 未定义(undef)的数值.不管该函数是否严格,我们都可以这么做.

复合类型的参数是当做指向散列的引用传递给函数的. 散列的键字是复合类型的属性名.下面是一个例子∶

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;

目前还没有任何形式的返回一个复合类型返回值的支持.

窍门: 因为函数体是以一个 SQL 字串文本的形式传递给 CREATE FUNCTION 的,你必须在你的 Perl 源码内部 逃逸单引号和反斜扛.通常就是象上面例子显示的那样写双份。 另外一个可能的途径是用 Perl 的扩展引起函数 (q[]qq[]qw[])来避免使用单引号.