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

Триггерные функции в PL/Tcl

примечание

Эта страница переведена при помощи нейросети GigaChat.

Триггерные функции могут быть написаны на PL/Tcl. PostgreSQL требует, чтобы функция, которая должна вызываться как триггер, была объявлена как функция без аргументов и с типом возврата trigger.

Информация от диспетчера триггеров передается в тело функции в следующих переменных:

$TG_name

Имя триггера из оператора CREATE TRIGGER.

$TG_relid

Идентификатор объекта таблицы, который вызвал функцию триггера.

$TG_table_name

Название таблицы, которая вызвала функцию триггера.

$TG_table_schema

Схема таблицы, которая вызвала функцию триггера.

$TG_relatts

Список имен столбцов таблицы Tcl, с префиксом из пустого элемента списка. Таким образом, поиск имени столбца в списке командой Tcl возвращает номер элемента, начиная с 1 для первого столбца, так же, как столбцы обычно нумеруются в PostgreSQL. Пустые элементы списка также появляются в позициях столбцов, которые были удалены, чтобы нумерация атрибутов была правильной для столбцов справа от них.

$TG_when

Строка BEFORE, AFTER, или INSTEAD OF, в зависимости от типа события триггера.

$TG_level

Строка ROW или STATEMENT в зависимости от типа события триггера.

$TG_op

Строка INSERT, UPDATE, DELETE, или TRUNCATE в зависимости от типа события триггера.

$NEW

Ассоциативный массив, содержащий значения новой строки таблицы для действий INSERT или UPDATE, или пустой для DELETE. Массив индексируется по имени столбца. Столбцы, которые имеют значение NULL, не будут отображаться в массиве. Это не установлено для триггеров уровня оператора.

$OLD

Ассоциативный массив, содержащий значения старой строки таблицы для действий UPDATE или DELETE, или пустой для INSERT. Массив индексируется по имени столбца. Столбцы, которые имеют значение NULL, не будут отображаться в массиве. Это не установлено для триггеров уровня оператора.

$args

Список Tcl из аргументов функции, заданных в операторе CREATE TRIGGER. Эти аргументы также доступны как $1 ... $n в теле функции.

Возвращаемое значение из функции триггера может быть одной из строк OK или SKIP, либо списком пар имя_столбца/значение. Если возвращаемым значением является OK, операция (INSERT/UPDATE/DELETE), которая вызвала триггер, будет продолжена нормально. SKIP сообщает менеджеру триггеров о том, что необходимо молча подавить операцию для этой строки. Если возвращается список, он указывает PL/Tcl вернуть измененную строку менеджеру триггеров; содержимое измененной строки определяется именами и значениями столбцов в списке. Все столбцы, не упомянутые в списке, устанавливаются равными NULL. Возвращение измененной строки имеет смысл только для триггеров уровня строки BEFORE INSERT или UPDATE, для которых вставляется измененная строка вместо той, которая указана в $NEW, или для триггеров уровня строки INSTEAD OF INSERT или UPDATE, где возвращаемая строка используется в качестве исходных данных для предложений INSERT RETURNING или UPDATE RETURNING. В триггерах уровня строки BEFORE DELETE или INSTEAD OF DELETE, возврат измененной строки оказывает такое же воздействие, как и возврат OK, то есть операция продолжается. Значение возврата триггера игнорируется для всех других типов триггеров.

Совет

Список результатов может быть создан из массива представления измененной кортежа с помощью команды array get Tcl.

Ниже представлена небольшая примерная функция триггера, которая заставляет целое значение в таблице отслеживать количество выполненных обновлений строки. Для новых вставленных строк значение инициализируется равным 0 и затем увеличивается при каждой операции обновления.

CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS $$
switch $TG_op {
INSERT {
set NEW($1) 0
}
UPDATE {
set NEW($1) $OLD($1)
incr NEW($1)
}
default {
return OK
}
}
return [array get NEW]
$$ LANGUAGE pltcl;

CREATE TABLE mytab (num integer, description text, modcnt integer);

CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
FOR EACH ROW EXECUTE FUNCTION trigfunc_modcount('modcnt');

Обратите внимание, что сама функция триггера не знает имя столбца, это передается из аргументов триггера. Это позволяет функции триггера повторно использоваться с разными таблицами.