支援的版本:目前 (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 函式由相同的 SQL 角色執行時,它們才會共享相同的 %_SHARED 值。在一個單一工作階段中,使用多個 SQL 角色(透過 SECURITY DEFINER 函式、使用 SET ROLE 等)執行程式碼的應用程式中,您可能需要採取明確的步驟,以確保 PL/Perl 函式可以透過 %_SHARED 共享資料。若要執行此操作,請確定應該通訊的函式由同一使用者擁有,並將它們標記為 SECURITY DEFINER。當然,您必須小心,確保這些函式不能用於執行任何非預期的操作。

提交更正

如果您在文件中發現任何不正確、與您的特定功能體驗不符或需要進一步澄清的地方,請使用此表單來回報文件問題。