Для создания функции на языке PL/Tcl используйте стандартный синтаксис CREATE FUNCTION syntax:
CREATE FUNCTIONимя_функции(типы_аргументов) RETURNSтип_результатаAS $$ # тело функции PL/Tcl $$ LANGUAGE pltcl;
PL/TclU аналогичен, за исключением того, что язык должен быть указан как
pltclu.
Тело функции представляет собой обычный скрипт на языке Tcl. При вызове функции значения аргументов передаются в Tcl-скрипт в виде переменных с именами 1
... . Результат возвращается из кода на языке Tcl обычным способом, с помощью nreturn оператора. В процедуре возвращаемое значение
кода Tcl игнорируется.
Например, функцию, возвращающую большее из двух целых чисел, можно определить следующим образом:
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
if {$1 > $2} {return $1}
return $2
$$ LANGUAGE pltcl STRICT;
Обратите внимание на предложение STRICT, которое избавляет от необходимости обрабатывать входные значения NULL: если передано значение NULL, функция не будет вызвана вовсе, а автоматически вернёт результат NULL.
В нестрогой функции,
если фактическое значение аргумента равно null, соответствующей
$ переменной будет присвоена пустая строка.
Чтобы определить, является ли конкретный аргумент значением null, используйте функцию
nargisnull. Например, предположим, что нам потребовалось, tcl_max
чтобы функция с одним аргументом 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;
Как показано выше,
чтобы вернуть значение null из функции PL/Tcl, выполните
return_null. Это можно сделать независимо от того, является ли функция строгой (strict) или нет.
Аргументы составных типов передаются в функцию в виде массивов 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 также могут возвращать результаты составных типов. Для этого код 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);
Результирующий список можно сформировать из представления нужного кортежа в виде массива с помощью 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 могут возвращать наборы данных (set). Для выполнения этого действия код на языке 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;