Chapter 39. PL/Perl - Perl 過程語言

Table of Contents
39.1. PL/Perl 函數和參數
39.2. PL/Perl 裡的數據值
39.3. 從 PL/Perl 裡訪問數據庫
39.4. 可信的和不可信的 PL/Perl
39.5. 缺少的特性

PL/Perl 是一種可裝載的過程語言,通過它我們可以用 Perl 編程語言寫 PostgreSQL 函數。

要在特定數據庫裡安裝 PL/Perl,使用 createlang plperl dbname

提示: 如果某種編程語言安裝到 template1,那麼所有隨後創建的數據庫都會自動安裝這種語言。

注意: 使用源碼包的用戶必須在安裝過程中特別打開 PL/Perl 的制作。 (請參考安裝指導獲取更多信息)。二進制包的用戶可能會在一些獨立的子包中找到 PL/Perl。

39.1. PL/Perl 函數和參數

要用 PL/Perl 語言創建一個函數,可以使用標準的語法

CREATE FUNCTION funcname (argument-types) RETURNS return-type AS '
    # PL/Perl function body
' LANGUAGE plperl;

函數體是普通的 Perl 代碼。

參數和結果都是和任何其它 Perl 子過程裡那樣處理的: 參數是放在 @_ 裡傳遞的, 結果值是用 return 返回或者作為函數中最後計算的表達式的值返回。

比如,一個返回兩個整數中較大值的函數可以這麼寫:

CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS '
    if ($_[0] > $_[1]) { return $_[0]; }
    return $_[1];
' LANGUAGE plperl;

如果給函數傳遞一個 SQL null 那麼其參數值將以 Perl 中 "undefined" 的形式出現。上面的函數定義在輸入為 null 時的行為不是很正常(實際上, 它將表現得好像它們都是零一樣)。我們可以給函數定義增加 STRICT,讓 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 函數中返回一個 SQL 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;

目前還沒有任何形式的返回一個復合類型值的支持。

提示: 因為函數體是以一個 SQL 字串文本的形式傳遞給 CREATE FUNCTION 的,你必須在你的 Perl 源碼內部逃逸單引號和反斜扛。 通常就是象上面例子顯示的那樣寫雙份。 另外一個可能的途徑是用 Perl 的擴展引起函數 (q[]qq[]qw[])來避免使用單引號。