pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
目录
PL/Perl 是一种可加载的过程语言,可以用 Perl 编程语言编写 PostgreSQL 函数。
要在某个特定数据库中安装 PL/Perl,使用 createlang plperl 。dbname
如果把某种语言安装到template1中,之后创建的所有数据库都会自动安装该语言。
使用源码包的用户必须在安装过程中专门启用 PL/Perl 的构建(更多信息见 第 14 章)。使用二进制包的用户可能会在单独的 子包中找到 PL/Perl。
要用 PL/Perl 语言创建一个函数,可使用标准语法:
CREATE FUNCTIONfuncname(argument-types) RETURNSreturn-typeAS $$ # 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 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。