Функции и аргументы PL/Tcl
Эта страница переведена при помощи нейросети GigaChat.
Для создания функции на языке PL/Tcl, используйте стандартный синтаксис CREATE FUNCTION:
CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$
# PL/Tcl function body
$$ LANGUAGE pltcl;
В PL/TclU команда аналогичная, за исключением того, что язык должен быть указан как pltclu
.
Тело функции представляет собой просто фрагмент сценария Tcl. Когда функция вызывается, значения аргументов передаются сценарию 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 также могут возвращать результаты составного типа. Для этого код 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;