40.6. Функции триггеров в PL/Tcl#
40.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, не будут присутствовать в массиве. Для триггеров на уровне оператора это значение не устанавливается.$argsTcl-список аргументов функции, заданных в операторе
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');
Обратите внимание, что сама триггерная функция не знает имя столбца; оно передается из аргументов триггера. Это позволяет повторно использовать триггерную функцию с разными таблицами.