要用 PL/Tcl 语言创建函数,请使用 标准的 CREATE FUNCTION 语法:
CREATE FUNCTIONfuncname(argument-types) RETURNSreturn-typeAS $$ # PL/Tcl function body $$ LANGUAGE pltcl;
PL/TclU 与之相同,只是语言必须被指定
为 pltclu。
函数体就是一段 Tcl 脚本。
当函数被调用时,参数值会以名为 1
... 的变量形式传给
Tcl 脚本。结果按常规方式从 Tcl 代码返回,
即使用 nreturn 语句。在过程中,Tcl 代码的返回值
会被忽略。
例如,一个返回两个整数值中较大者的函数可以定义为:
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
if {$1 > $2} {return $1}
return $2
$$ LANGUAGE pltcl STRICT;
注意 STRICT 子句,它使我们免于考虑空输入
值:如果传入空值,函数根本不会被调用,而会自动返回一个空
结果。
在非严格函数中,如果某个参数的实际值为空,相应的
$ 变量会被设置为
空字符串。要检测某个特定参数是否为空,请使用函数
nargisnull。例如,假设我们希望
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;