PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 41. PL/Tcl - Tcl 过程语言 | 下一页

# 41.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`语句。

比如，一个简单的返回两个整数值中较大值的函数可以这样定义：

    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目前还不是完全支持域类型：它看待域类型和下层的标量类型是一样的。 这就意味着与域关联的约束将不会被强制。对于函数参数，这不是什么问题， 但是如果你把PL/Tcl函数声明为返回一个域类型，那么就有危险。

上一页 | 起始页 | 下一页
概述 | 上一级 | PL/Tcl里的数据值