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 脚本。结果会以常见的方式通过一个return从 Tcl 脚本中返回。
例如,一个返回两个整数值中较大值的函数可以定义为:
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ if {$1 > $2} {return $1} return $2 $$ LANGUAGE pltcl STRICT;
注意子句STRICT,它让我们不用去操心空输入值:如果空值被传入,函数根本就不会被调用,而是自动地返回一个空结果。
在非严格函数中,如果一个参数的实际值为空,对应的$n变量将被设置为一个空串。为了检测一个特定参数是否为空,可使用函数argisnull。例如,假设我们想要带有一个空参数和一个非空参数并且返回非空参数的tcl_max
:
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 函数返回空值,可执行return_null。不管函数是严格还是非严格都可以这样做。
组合类型参数会被作为 Tcl 数组传递给函数。该数组的元素名就是组合类型的属性值。如果被传入行的一个属性为空值,它不会出现在数组中。这里是一个例子:
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函数为返回域类型就会造成灾难。