41.6. Функции триггеров в PL/Tcl#
41.6. Функции триггеров в PL/Tcl #
Функции триггеров могут быть написаны на PL/Tcl.
Tantor BE требует, чтобы функция, которая должна быть вызвана
как триггер, была объявлена как функция без аргументов
и с типом возвращаемого значения trigger
.
Информация от менеджера триггеров передается в тело функции в следующих переменных:
$TG_name
Имя триггера из оператора
CREATE TRIGGER
.$TG_relid
Идентификатор объекта таблицы, вызвавшей триггерную функцию.
$TG_table_name
Имя таблицы, вызвавшей триггерную функцию.
$TG_table_schema
Схема таблицы, вызвавшей триггерную функцию.
$TG_relatts
Список столбцов таблицы на языке Tcl, с префиксом пустого элемента списка. Таким образом, поиск имени столбца в списке с помощью команды Tcl
lsearch
возвращает номер элемента, начиная с 1 для первого столбца, так же, как принято нумеровать столбцы в Tantor BE. (Пустые элементы списка также появляются на позициях столбцов, которые были удалены, чтобы нумерация атрибутов была правильной для столбцов справа).$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
, то есть операция выполняется. Значение, возвращаемое триггером, игнорируется для всех остальных типов триггеров.
Подсказка
Список результатов может быть создан из массивного представления измененного кортежа с помощью команды Tcl array get
.
Вот небольшой пример триггерной функции, которая заставляет целочисленное значение в таблице отслеживать количество обновлений, выполняемых для строки. Для новых вставленных строк значение инициализируется нулем, а затем увеличивается при каждой операции обновления.
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');
Обратите внимание, что сама триггерная функция не знает имя столбца; оно передается из аргументов триггера. Это позволяет повторно использовать триггерную функцию с разными таблицами.