Existe uma boa maneira de executar um gatilho para cada registro em uma tabela do postgres?

22

Eu tenho um sistema em que não posso controlar o design de algumas tabelas (replicadas via Slony-I) e, portanto, tenho uma série do que chamamos de 'tabelas de sombra', onde extraio algumas informações das tabelas replicadas e armazene-o no formulário processado de que preciso, enquanto retira os registros que quero ignorar.

No momento, depois de configurar uma nova réplica, eu executo uma atualização e defino um valor novamente (por exemplo, UPDATE tablename SET field=field) para forçar a execução do gatilho, mas algumas das tabelas têm milhões de registros e estão crescendo, e isso pode levar 30 minutos . (e depois há o vácuo também).

Existe alguma maneira melhor de acioná-lo ou de escrever uma função que funcione com a entrada passada ou NEWdependendo do contexto de chamada? Estou relutante em manter duas funções diferentes por aí, como já vi muitas vezes em que uma é atualizada, e não a outra.

Joe
fonte
Eu sabia como acionar um gatilho ... Perguntei se havia um bom caminho.
Joe

Respostas:

19

Isso pode ser feito usando o seguinte modelo:

CREATE TABLE tablename ( ... );

/* for direct invocation */
CREATE FUNCTION propagate_data(newrow tablename) RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO other_table VALUES (newrow.a, newrow.b, ...);
END:
$$;

/* trigger function wrapper */
CREATE FUNCTION propagate_data_trg() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
    PERFORM propagate_data(NEW);
END;
$$;

CREATE TRIGGER propagate_data AFTER INSERT ON tablename FOR EACH ROW
    EXECUTE PROCEDURE propagate_data_trg();
Peter Eisentraut
fonte
Doh ... Eu estava pensando nisso de trás para a frente (tentando tornar a função de acionamento acionável por um procedimento, não vice-versa).
Joe
1
Quando eu realmente fiz isso, percebi que 'linha' era uma palavra reservada, então corrigi o exemplo para que outros não passassem tanto tempo depurando.
Joe
1
Eu realmente deveria ter seguido anos atrás. Demorei um tempo até que eu conseguisse fazer tudo funcionar no meu sistema ... e esse método funciona, mas o desempenho foi péssimo. (passou de 30 minutos para mais de um dia para ser concluído).
Joe