36.2. PL/Tcl 函數和參數

要用PL/Tcl語言建立一個函數,使用標準的語法:

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

PL/TclU是一樣的,除了語言應該聲明為 pltclu 之外。

函數體就是一段 Tcl 代碼。 當在一個查詢裡面調用這個函數, 參數是作為變量 $1 ... $n 傳遞給 Tcl 腳本的。 結果是用通常的方法從 Tcl 代碼中返回的,就是用一個 return 語句。

比如, 一個簡單的返回兩個整數值的最大值函數可以這樣定義:

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_2 (EMP) 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 目前還不是完全支援域類型:它看待域類型和下層的標量類型是一樣的。 這就意味著與域關聯的約束將不會被強制。對於函數參數,這不是什麼問題, 但是如果您把 PL/Tcl 函數聲明為返回一個域類型,那麼就有危險。