On this page
44.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 代码返回结果。在一个过程中,将忽略 Tcl 代码的返回值。
例如,返回两个整数值中较大的一个的函数可以定义为:
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
if {$1 > $2} {return $1}
return $2
$$ LANGUAGE pltcl STRICT;
请注意条款STRICT
,这使我们不必考虑空 Importing 值:如果传递了空值,则根本不会调用该函数,而只会自动返回空结果。
在非严格函数中,如果参数的实际值为 null,则相应的$n
变量将设置为空字符串。要检测特定参数是否为空,请使用函数argisnull
。例如,假设我们希望tcl_max
带有一个 null 和一个 nonnull 参数来返回 nonnull 参数,而不是 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 函数返回空值,请执行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 代码必须返回与预期结果类型匹配的列名/值对的列表。列表中省略的任何列名都将返回 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);
Tip
结果列表可以使用array get
Tcl 命令从所需 Tuples 的数组表示形式中得出。例如:
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;