要在 PL/Tcl 语言中创建函数,请使用标准的 CREATE FUNCTION 语法。
CREATE FUNCTIONfuncname
(argument-types
) RETURNSreturn-type
AS $$ # PL/Tcl function body $$ LANGUAGE pltcl;
PL/TclU 是相同的,只是语言必须指定为 pltclu
。
函数的主体只是一段 Tcl 脚本。当调用函数时,参数值会作为名为 1
...
的变量传递给 Tcl 脚本。结果以通常的方式从 Tcl 代码中返回,使用 n
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 函数也可以返回复合类型的结果。为此,Tcl 代码必须返回一个与预期结果类型匹配的列名/值对列表。列表中省略的任何列名都将返回为空值,如果存在意外的列名,则会引发错误。这是一个例子:
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 命令从所需元组的数组表示形式创建结果列表。例如:
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;
如果您在文档中看到任何不正确、与您使用特定功能的体验不符或需要进一步澄清的内容,请使用此表单报告文档问题。