可以在函数调用之间或者当前会话的生命期中用全局哈希
%_SHARED来存储数据,包括代码引用。
这是共享数据的一个简单例子:
CREATE OR REPLACE FUNCTION set_var(name text, val text) RETURNS text AS $$
if ($_SHARED{$_[0]} = $_[1]) {
return 'ok';
} else {
return "cannot set shared variable $_[0] to $_[1]";
}
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION get_var(name text) RETURNS text AS $$
return $_SHARED{$_[0]};
$$ LANGUAGE plperl;
SELECT set_var('sample', 'Hello, PL/Perl! How''s tricks?');
SELECT get_var('sample');
这是一个使用代码引用的稍微复杂一点的例子:
CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$
$_SHARED{myquote} = sub {
my $arg = shift;
$arg =~ s/(['\\])/\\$1/g;
return "'$arg'";
};
$$ LANGUAGE plperl;
SELECT myfuncs(); /* 初始化函数 */
/* 设置一个使用引用函数的函数 */
CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$
my $text_to_quote = shift;
my $qfunc = $_SHARED{myquote};
return &$qfunc($text_to_quote);
$$ LANGUAGE plperl;
(你可以把上面的代码用一行
return $_SHARED{myquote}->($_[0]);替换,
代价是牺牲了可读性)。
处于安全原因,PL/Perl 一个 SQL 角色独立的 Perl 解释器中执行该角色调用
的任何一个函数。这可以避免一个用户无意或者恶意地干涉另一个用户的
PL/Perl 函数的行为。每一个这样的解释器都具有其自身的
%_SHARED变量值和其他全局状态。因此,只有当
两个 PL/Perl 函数是由同一个 SQL 角色执行时,它们才能共享同一个
%_SHARED值。在使用单个会话执行多个 SQL 角色
的代码(通过SECURITY DEFINER函数、使用
SET ROLE等)的应用中,需要采取显式的步骤以保证 PL/Perl
函数能够通过%_SHARED共享数据。要这样做,需要
确保要通信的函数都属于同一个用户,并且把它们标记为
SECURITY DEFINER。当然,要小心这样的函数被滥用。