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