codecamp

PostgreSQL PL/Perl 中的全局值

可以在函数调用之间或者当前会话的生命期中用全局哈希 %_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。当然,要小心这样的函数被滥用。

PostgreSQL 内建函数
PostgreSQL 可信的和不可信的 PL/Perl
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

PostgreSQL SQL语言

PostgreSQL 服务器管理

PostgreSQL 客户端接口

PostgreSQL 服务器编程

PostgreSQL 参考

PostgreSQL 内部

PostgreSQL 附录

PostgreSQL 参考书目

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }