Las funciones de disparo se pueden escribir en PL/Tcl.
PostgreSQL requiere que una función que se va a llamar
como disparador se declare como una función sin argumentos
y con un tipo de retorno de trigger.
La información del gestor de disparadores se pasa al cuerpo de la función en las siguientes variables:
$TG_name
El nombre del disparador de la sentencia CREATE TRIGGER.
$TG_relidEl ID de objeto de la tabla que causó la invocación de la función de disparo.
$TG_table_nameEl nombre de la tabla que causó la invocación de la función de disparo.
$TG_table_schemaEl esquema de la tabla que causó la invocación de la función de disparo.
$TG_relatts
Una lista de Tcl con los nombres de las columnas de la tabla, con un elemento de lista vacío
como prefijo. De modo que buscar un nombre de columna en la lista con el comando
lsearch de Tcl devuelve el número del elemento comenzando
con 1 para la primera columna, de la misma manera que las columnas se numeran habitualmente
en PostgreSQL. (Los elementos de lista vacíos
también aparecen en las posiciones de las columnas que han sido
eliminadas, de modo que la numeración de atributos es correcta para las columnas
a su derecha).
$TG_when
La cadena BEFORE, AFTER o
INSTEAD OF, según el tipo de evento del disparador.
$TG_level
La cadena ROW o STATEMENT, según el
tipo de evento del disparador.
$TG_op
La cadena INSERT, UPDATE,
DELETE o TRUNCATE, según el tipo de
evento del disparador.
$NEW
Un array asociativo que contiene los valores de la nueva fila de la
tabla para las acciones INSERT o UPDATE, o
vacío para DELETE. El array está indexado por el nombre de la
columna. Las columnas que son null no aparecerán en el array.
Esto no se establece para los disparadores a nivel de sentencia.
$OLD
Un array asociativo que contiene los valores de la antigua fila de la
tabla para las acciones UPDATE o DELETE, o
vacío para INSERT. El array está indexado por el nombre de la
columna. Las columnas que son null no aparecerán en el array.
Esto no se establece para los disparadores a nivel de sentencia.
$args
Una lista de Tcl con los argumentos de la función tal como se proporcionan en la
sentencia CREATE TRIGGER. Estos argumentos también son accesibles como
$1 ... $ en el cuerpo de la función.
n
El valor de retorno de una función de disparo puede ser una de las cadenas
OK o SKIP, o una lista de pares nombre/valor de columna.
Si el valor de retorno es OK,
la operación (INSERT/UPDATE/DELETE)
que activó el disparador continuará
normalmente. SKIP le dice al gestor de disparadores que suprima silenciosamente
la operación para esta fila. Si se devuelve una lista, le dice a PL/Tcl que
devuelva una fila modificada al gestor de disparadores; los contenidos de la
fila modificada se especifican mediante los nombres de las columnas y los valores en la lista.
Cualquier columna no mencionada en la lista se establece en null.
Devolver una fila modificada solo es significativo
para disparadores a nivel de fila BEFORE INSERT o UPDATE,
para los cuales la fila modificada se insertará en lugar de la
proporcionada en $NEW; o para disparadores a nivel de fila INSTEAD OF
INSERT o UPDATE donde la fila devuelta
se utiliza como datos de origen para las cláusulas INSERT RETURNING o
UPDATE RETURNING.
En disparadores a nivel de fila BEFORE DELETE o INSTEAD
OF DELETE, devolver una fila modificada tiene el mismo
efecto que devolver OK, es decir, la operación continúa.
El valor de retorno del disparador se ignora para todos los demás tipos de disparadores.
La lista de resultados se puede crear a partir de una representación en array de la
tupla modificada con el comando Tcl array get.
Aquí tienes un pequeño ejemplo de función de disparo que fuerza a un valor entero en una tabla a realizar un seguimiento del número de actualizaciones que se realizan en la fila. Para las nuevas filas insertadas, el valor se inicializa a 0 y luego se incrementa en cada operación de actualización.
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');
Observa que la función de disparo en sí no conoce el nombre de la columna; se proporciona a partir de los argumentos del disparador. Esto permite que la función de disparo se reutilice con diferentes tablas.