2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 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);

提示

结果列表可以通过 Tcl 命令 array get 从所需元组的数组表示中构成。例如。

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;

提交更正

如果您在文档中发现任何不正确之处、与您对特定功能的体验不符之处或需要进一步澄清之处,请使用 此表单 报告文档问题。