<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 42.1\. PL/Perl 函數和參數 要用 PL/Perl 語言創建一個函數,可以使用標準的[CREATE FUNCTION](#calibre_link-4)語法: ``` CREATE FUNCTION _funcname_ (_argument-types_) RETURNS _return-type_ AS $$ # PL/Perl function body $$ LANGUAGE plperl; ``` 函數體是普通 Perl 代碼。實際上,PL/Perl 膠水代碼將其封裝在一個 Perl 子過程里。 一個 PL/Perl 函數在一個標量環境中調用,所以不能返回一個列表。 你可以像下面描述的那樣用返回引用的方法返回非標量值(arrays, records, 和 sets)。 PL/Perl也支持[DO](#calibre_link-521)語句調用匿名代碼塊: ``` DO $$ # PL/Perl code $$ LANGUAGE plperl; ``` 一個匿名代碼塊不接收參數,而且丟棄任何返回值。否則它的行為就像一個函數。 > **Note:** 在 Perl 里使用命名的嵌套子過程是很危險的,特別是它們在閉包里引用了詞法變量的時候。 因為 PL/Perl 是封裝在一個子過程里,因此,任何你放進去的命名子過程都將被嵌套。通常, 創建一個用 coderef 調用的匿名子過程要安全得多。想要獲取更多細節,請參閱 `Variable "%s" will not stay shared`里的記錄或 perldiag手冊頁中的`Variable "%s" is not available`, 或在Internet上搜索"perl 嵌套命名子過程"。 `CREATE FUNCTION`命令的語法要求把函數體寫成字符串常量。 通常處理字符串文本用美元符界定更方便(參閱[Section 4.1.2.4](#calibre_link-736)), 如果你想使用傳統的`E''`逃逸語法,必須雙寫函數體里使用的任何單引號(`'`) 和反斜杠(`\`)(參見[Section 4.1.2.1](#calibre_link-969))。 參數和結果都是和任何其它 Perl 子過程里那樣處理的:參數是放在`@_`里傳遞的, 結果值是用`return`返回或者作為函數中最后計算的表達式的值返回。 比如,一個返回兩個整數中較大值的函數可以這么寫: ``` CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ if ($_[0] > $_[1]) { return $_[0]; } return $_[1]; $$ LANGUAGE plperl; ``` > **Note:** 為了能夠在PL/Perl里使用,參數將從數據庫編碼轉換為UTF-8,然后在返回時從UTF-8回到數據庫編碼。 如果給函數傳遞一個 NULL 那么其參數值將以 Perl 中"undefined" 的形式出現。上面的函數定義在輸入為 NULL 時的行為不是很正常(實際上, 它將表現得好像它們都是零一樣)。可以給函數定義增加`STRICT`讓 PostgreSQL做一些更合理的事情:如果傳遞進來一個 NULL , 那么該函數則根本不會被調用,而只是自動返回一個 NULL 結果。另外, 可以在函數體里檢查未定義的輸入。比如,假設想收到一個 NULL 和一個非 NULL 參數的 `perl_max`返回非 NULL 的參數,而不是 NULL : ``` CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ my ($x, $y) = @_; if (not defined $x) { return undef if not defined $y; return $y; } return $x if not defined $y; return $x if $x > $y; return $y; $$ LANGUAGE plperl; ``` 如上所述,要從 PL/Perl 函數中返回一個 NULL ,可以返回一個未定義的數值。 不管該函數是否嚴格,都可以這么做。 任何一個不是引用的函數參數是一個字符串,這是相關數據類型在標準PostgreSQL 外部文本里的表示。普通數字或文本類型的情況下,Perl將只是做正確的事情,程序員不需要擔心。 然而,在其他情況下,需要將參數轉換為Perl可用的形式。例如,`decode_bytea` 函數可以用來轉換類型`bytea`的參數為非逃逸的二進制。 相似的,傳回PostgreSQL的值必須是外部文本表示格式。 例如,`encode_bytea`函數可以用來為一個類型為`bytea` 的返回值逃逸二進制數據。 Perl 可以用 Perl 數組引用的方式返回PostgreSQL數組。 下面是一個例子: ``` CREATE OR REPLACE function returns_array() RETURNS text[][] AS $$ return [['a"b','c,d'],['e\\f','g']]; $$ LANGUAGE plperl; select returns_array(); ``` Perl作為一個`PostgreSQL::InServer::ARRAY`對象傳遞PostgreSQL 數組。這個對象可以被視為一個數組引用或一個字符串,Perl為PostgreSQL 低于9.1的版本編寫了代碼,允許向后兼容。例如: ``` CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ my $arg = shift; my $result = ""; return undef if (!defined $arg); # as an array reference for (@$arg) { $result .= $_; } # also works as a string $result .= $arg; return $result; $$ LANGUAGE plperl; SELECT concat_array_elements(ARRAY['PL','/','Perl']); ``` > **Note:** 多維數組的表現就和每個Perl程序員引用低維數組的引用一樣。 復合類型的參數是當做指向散列的引用傳遞給函數的。散列的鍵字是復合類型的屬性名。下面是一個例子: ``` 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; ``` 使用同樣的辦法,一個 PL/Perl 函數可以返回一個復合類型的結果: 返回一個包含所需要的屬性的散列的引用。比如, ``` CREATE TYPE testrowperl AS (f1 integer, f2 text, f3 text); CREATE OR REPLACE FUNCTION perl_row() RETURNS testrowperl AS $$ return {f2 => 'hello', f1 => 1, f3 => 'world'}; $$ LANGUAGE plperl; SELECT * FROM perl_row(); ``` 在聲明的結果數據類型里的任何字段如果在散列里面沒有出現,那么都會當作 NULL 返回。 PL/Perl 函數也能返回標量或者復合類型的集合。通常你希望一次返回一行, 一方面加速函數啟動時間,另外一方面防止在內存里堆積整個結果集。 可以用下面說明的函數`return_next`。請注意在最后的 `return_next`,你必須放一個 `return` 或者(最好是)`return undef`。 ``` CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$ foreach (0..$_[0]) { return_next($_); } return undef; $$ LANGUAGE plperl; SELECT * FROM perl_set_int(5); CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$ return_next({ f1 => 1, f2 => 'Hello', f3 => 'World' }); return_next({ f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' }); return_next({ f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' }); return undef; $$ LANGUAGE plperl; ``` 對于小的結果集,你可以返回一個指向一個數組的引用,這個數組可以包含標量,指向數組的引用, 或者指向簡單類型,數組類型以及復合類型等的散列的引用。這里是一個簡單的例子, 它把整個結果集當作一個數組引用返回: ``` CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$ return [0..$_[0]]; $$ LANGUAGE plperl; SELECT * FROM perl_set_int(5); CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$ return [ { f1 => 1, f2 => 'Hello', f3 => 'World' }, { f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' }, { f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' } ]; $$ LANGUAGE plperl; SELECT * FROM perl_set(); ``` 如果你想在自己的代碼里使用`strict`用法你有幾種選擇。對于臨時全局使用你可以 `SET` `plperl.use_strict`為真。這個參數影響隨后的PL/Perl 函數的編譯,但是不影響在當前會話里已經編譯了的函數。為了永久全局使用, 可以在`postgresql.conf`文件里設置`plperl.use_strict`為真。 要在特定的函數中永久使用,只需要簡單地在函數體的頂部放置: ``` use strict; ``` 如果你的Perl是版本5.10.0或更高,那么`feature`程序也適用于`use`。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看