42.6. Funções de gatilho em PL/Tcl #

Podem ser escritas funções de gatilho em PL/Tcl. O PostgreSQL requer que uma função que será chamada como um gatilho seja declarada como uma função sem argumentos, e retornado o tipo de dados trigger.

As informações do gerenciador de gatilhos são passadas para o corpo da função nas seguintes variáveis:

$TG_name

O nome do gatilho da instrução CREATE TRIGGER.

$TG_relid

O identificador (ID) do objeto da tabela que causou a chamada da função de gatilho.

$TG_table_name

O nome da tabela que causou a chamada da função de gatilho.

$TG_table_schema

O esquema da tabela que causou a chamada da função de gatilho.

$TG_relatts

Uma lista Tcl dos nomes das colunas da tabela, prefixada com um elemento de lista vazio. Portanto, procurar o nome de uma coluna na lista com o comando lsearch do PL/Tcl retorna o número do elemento começando com 1 para a primeira coluna, da mesma forma que as colunas são normalmente numeradas no PostgreSQL. (Os elementos da lista vazios também aparecem nas posições das colunas que foram eliminadas, para que a numeração dos atributos seja correta para as colunas à sua direita.)

$TG_when

A cadeia de caracteres BEFORE, AFTER, ou INSTEAD OF, dependendo do tipo de evento do gatilho.

$TG_level

A cadeia de caracteres ROW ou STATEMENT, dependendo do tipo de evento do gatilho.

$TG_op

A cadeia de caracteres INSERT, UPDATE, DELETE, ou TRUNCATE, dependendo do tipo de evento do gatilho.

$NEW

Uma matriz associativa contendo os valores da nova linha da tabela para as ações INSERT ou UPDATE, ou vazio para DELETE. A matriz é indexada pelo nome da coluna. As colunas nulas não aparecem na matriz. Não está definida para gatilhos no nível de instrução.

$OLD

Uma matriz associativa contendo os valores antigos da linha da tabela para as ações INSERT ou UPDATE, ou vazio para DELETE. A matriz é indexada pelo nome da coluna. As colunas nulas não aparecem na matriz. Não está definida para gatilhos no nível de instrução.

$args

Uma lista Tcl dos argumentos para a função conforme fornecido na instrução CREATE TRIGGER. Estes argumentos também são acessíveis como $1 ... $n no corpo da função.

O valor retornado por uma função de gatilho pode ser uma das cadeias de caracteres OK ou SKIP, ou uma lista de pares nome/valor de coluna. Se o valor retornado for OK, a operação (INSERT/UPDATE/DELETE) que disparou o gatilho irá prosseguir normalmente. SKIP diz ao gerenciador de gatilhos para suprimir silenciosamente a operação para esta linha. Se for retornada uma lista, ela irá informar ao PL/Tcl para retornar uma linha modificada ao gerenciador de gatilhos; o conteúdo da linha modificada é especificado pelos nomes e valores das colunas na lista. Quaisquer colunas não mencionadas na lista serão definidas como nulas. Retornar uma linha modificada só faz sentido para gatilhos BEFORE INSERT ou UPDATE no nível de linha, para os quais a linha modificada será inserida em vez daquela fornecida em $NEW; ou para gatilhos INSTEAD OF INSERT ou UPDATE no nível de linha, onde a linha retornada é usada como dados de origem para as cláusulas INSERT RETURNING ou UPDATE RETURNING. Nos gatilhos BEFORE DELETE ou INSTEAD OF DELETE no nível de linha, retornar uma linha modificada tem o mesmo efeito que retornar OK, ou seja, a operação prossegue. O valor retornado pelo gatilho é ignorado para todos os outros tipos de gatilhos.

Dica

A lista de resultados pode ser construída a partir de uma representação matricial da tupla modificada com o comando array get do Tcl.

A seguir está um pequeno exemplo de função de gatilho que força um valor inteiro em uma tabela para acompanhar o número de atualizações executadas na linha. Para as novas linhas inseridas o valor é inicializado em 0, e depois incrementado a cada operação de atualização.

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');

Note que a própria função de gatilho não conhece o nome da coluna; ele é fornecido pelos argumentos do gatilho. Isto permite que a função de gatilho seja reutilizada em tabelas diferentes.