|
25.3. 描述25.3.1. PL/Perl 函数和参数要用 PL/Perl 语言创建一个函数,可以使用标准的语法 CREATE FUNCTION funcname ( argument-types ) RETURNS return-type AS ' # PL/Perl function body ' LANGUAGE plperl; PL/PerlU 是一样的,只不过声明的语言应该是 plperlu . 函数体是普通的 Perl 代码.参数和结果都是和任何其它 Perl 子过程 一样处理∶参数是放在 @_ 里传递的, 结果值是用 return 或者函数中计算的最后的表达式 计算的.比如,一个返回两个整数中较大值的函数可以这么写∶ CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS ' if ($_[0] > $_[1]) { return $_[0]; } return $_[1]; ' LANGUAGE plperl; 如果给函数传递一个 NULL,那么其参数值将以 Perl 中 "undefined" 的形式出现.上面的函数定义对 NULL 输入将处理得非常好(实际上, 它将表现得好像它们都是零一样).我们可以给函数定义增加 WITH (isStrict) ,让 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 函数中返回一个 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;
目前还没有任何形式的返回一个复合类型返回值的支持.
下面是一个不能运行的函数的例子,因为出于安全原因,我们不 允许文件系统操作∶ CREATE FUNCTION badfunc() RETURNS integer AS ' open(TEMP, ">/tmp/badfile"); print TEMP "Gotcha!\n"; return 1; ' LANGUAGE plperl; 此函数的创建将会成功,但是执行不了. 请注意,如果同样的函数由超级用户用 plperlu 语言创建, 那么执行就会成功. 25.3.2. PL/Perl 里的数据值给 PL/Perl 函数的脚本提供的参数值都只是转换成文本形式 的输入参数(就象它们在 SELECT 语句中显示出来的那样). 相反, return 命令会接受任何该函数声明的返回类型 可以接受的输入格式.因此,PL/Perl 程序员可以把数据值当做 文本来操作. 25.3.3. 在 PL/Perl 里访问数据库从你的 Perl 函数内部访问数据库本身可以通过一个 试验模块 DBD::PgSPI 完成(也可以在 CPAN 镜像站 获得.)这个模块可以给我们一个兼容 DBI 的数据库 句柄,叫做 $pg_dbh ,你可以用它用普通的 DBI 语法执行查询. PL/Perl 本身目前只提供一个额外的 Perl 命令∶
25.3.4. 缺失的特性PL/Perl 函数不能直接相互调用(因为它们在 Perl 内部是匿名子过程). 目前它们之间也没有办法共享全局变量. 目前我们不能用 PL/Perl 写触发器函数. 应该把 DBD::PgSPI 或者类似的功能集成到标准的 PostgreSQL 版本中. |