2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0

43.4. 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(); /* initializes the function */

/* Set up a function that uses the quote function */

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 函式將共享相同的 %_SHARED 值,當且僅當它們由相同的 SQL 角色執行時。在一個會話中透過多個 SQL 角色執行程式碼的應用程式中(例如透過 SECURITY DEFINER 函式、使用 SET ROLE 等),您可能需要採取明確的步驟來確保 PL/Perl 函式可以透過 %_SHARED 共享資料。為此,請確保應該通訊的函式由同一個使用者擁有,並將它們標記為 SECURITY DEFINER。當然,您必須注意確保這些函式不會被用於執行任何意外操作。

提交更正

如果您在本應正確、與您對特定功能的經驗相符或需要進一步澄清的文件中看到任何內容,請使用此表單報告文件問題。