Перейти к основному содержимому

Функции и аргументы 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;