支援的版本: 目前 (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 / 7.4

42.2. PL/Tcl 函數與引數 #

若要以 PL/Tcl 語言建立函數,請使用標準的 CREATE FUNCTION 語法

CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$
    # PL/Tcl function body
$$ LANGUAGE pltcl;

PL/TclU 相同,只是語言必須指定為 pltclu

函數的主體只是一段 Tcl 腳本。當函數被呼叫時,引數值會以變數 1 ... n 的名稱傳遞給 Tcl 腳本。結果會以通常的方式從 Tcl 程式碼傳回,使用 return 陳述式。在程序中,來自 Tcl 程式碼的傳回值會被忽略。

例如,一個傳回兩個整數值中較大值的函數可以定義為

CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
    if {$1 > $2} {return $1}
    return $2
$$ LANGUAGE pltcl STRICT;

請注意 STRICT 子句,它使我們不必考慮 Null 輸入值:如果傳遞 Null 值,則根本不會呼叫該函數,而是自動傳回 Null 結果。

在非嚴格函數中,如果引數的實際值為 Null,則對應的 $n 變數將設定為空字串。若要偵測特定引數是否為 Null,請使用函數 argisnull。例如,假設我們希望 tcl_max 具有一個 Null 和一個非 Null 引數,傳回非 Null 引數,而不是 Null

CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
    if {[argisnull 1]} {
        if {[argisnull 2]} { return_null }
        return $2
    }
    if {[argisnull 2]} { return $1 }
    if {$1 > $2} {return $1}
    return $2
$$ LANGUAGE pltcl;

如上所示,若要從 PL/Tcl 函數傳回 Null 值,請執行 return_null。無論函數是否嚴格,都可以執行此操作。

複合類型引數以 Tcl 陣列的形式傳遞給函數。陣列的元素名稱是複合類型的屬性名稱。如果傳遞的列中的屬性具有 Null 值,則它不會出現在陣列中。這是一個範例

CREATE TABLE employee (
    name text,
    salary integer,
    age integer
);

CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
    if {200000.0 < $1(salary)} {
        return "t"
    }
    if {$1(age) < 30 && 100000.0 < $1(salary)} {
        return "t"
    }
    return "f"
$$ LANGUAGE pltcl;

PL/Tcl 函數也可以傳回複合類型結果。為此,Tcl 程式碼必須傳回符合預期結果類型的欄位名稱/值配對清單。從清單中省略的任何欄位名稱都會傳回為 Null,如果存在意外的欄位名稱,則會引發錯誤。這是一個範例

CREATE FUNCTION square_cube(in int, out squared int, out cubed int) AS $$
    return [list squared [expr {$1 * $1}] cubed [expr {$1 * $1 * $1}]]
$$ LANGUAGE pltcl;

程序的輸出引數以相同的方式傳回,例如

CREATE PROCEDURE tcl_triple(INOUT a integer, INOUT b integer) AS $$
    return [list a [expr {$1 * 3}] b [expr {$2 * 3}]]
$$ LANGUAGE pltcl;

CALL tcl_triple(5, 10);

提示

可以使用 array get Tcl 命令從所需 Tuple 的陣列表示建立結果清單。例如

CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$
    set 1(salary) [expr {$1(salary) + $2}]
    return [array get 1]
$$ LANGUAGE pltcl;

PL/Tcl 函數可以傳回集合。為此,Tcl 程式碼應為要傳回的每一列呼叫一次 return_next,傳遞適當的值(傳回純量類型時)或欄位名稱/值配對清單(傳回複合類型時)。這是一個傳回純量類型的範例

CREATE FUNCTION sequence(int, int) RETURNS SETOF int AS $$
    for {set i $1} {$i < $2} {incr i} {
        return_next $i
    }
$$ LANGUAGE pltcl;

這是一個傳回複合類型的範例

CREATE FUNCTION table_of_squares(int, int) RETURNS TABLE (x int, x2 int) AS $$
    for {set i $1} {$i < $2} {incr i} {
        return_next [list x $i x2 [expr {$i * $i}]]
    }
$$ LANGUAGE pltcl;

提交更正

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