depuração gatilho postgresql

votos
20

Eu tenho esse disparador no PostgreSQL que eu não pode simplesmente começar a trabalhar (não faz nada). Para compreensão, não é como eu o definiu:

CREATE TABLE documents (
    ...
    modification_time timestamp with time zone DEFAULT now()
);

CREATE FUNCTION documents_update_mod_time() RETURNS trigger
AS $$
    begin
    new.modification_time := now();
    return new;
    end
$$
    LANGUAGE plpgsql;

CREATE TRIGGER documents_modification_time
    BEFORE INSERT IGNORE  OR UPDATE ON documents
    FOR EACH ROW
    EXECUTE PROCEDURE documents_update_mod_time();

Agora, para torná-lo um pouco mais interessante .. Como você depurar gatilhos?

Publicado 20/11/2008 em 19:54
fonte usuário
Em outras línguas...                            


3 respostas

votos
3

Você pode usar 'levantar Aviso' declarações dentro de sua função de gatilho para depurá-lo. Para depurar o gatilho não sendo chamado a todos é uma outra história.

Se você adicionar um 'excepção raise' dentro de sua função de gatilho, você ainda pode fazer inserções / atualizações?

Além disso, se o seu teste de atualização ocorre na mesma transação como seu teste de inserção, agora () será o mesmo (uma vez que ele só é calculada uma vez por transação) e, portanto, a atualização não parece fazer nada. Se for esse o caso, ou fazê-los em transações separadas, ou se este é um teste de unidade e você não pode fazer isso, use clock_timestamp ().

Eu tenho um teste de unidade que depende de algum tempo passando por entre as transações, por isso no início do teste de unidade Eu tenho algo como:

ALTER TABLE documents
   ALTER COLUMN modification_time SET DEFAULT clock_timestamp();

Em seguida, no gatilho, usar "set modification_time = default".

Então, normalmente ele não faz o cálculo extra, mas durante um teste de unidade isso me permite fazer inserções com pg_sleep no meio para simular a passagem do tempo e, na verdade, tem que ser refletido nos dados.

Respondeu 20/11/2008 em 20:15
fonte usuário

votos
3

Acontece que eu estava usando herança no problema acima e esqueceu de mencioná-lo. Agora para todo mundo que pode executar para esse bem, aqui estão algumas dicas de depuração:

Use o seguinte código para depurar o que um gatilho está fazendo:

RAISE NOTICE 'test';       -- either this
RAISE EXCEPTION 'failed';  -- or that

Para ver o que desencadeia na verdade são chamados, quantas vezes etc, a seguinte declaração é o salva-vidas de escolha:

EXPLAIN ANALYZE UPDATE table SET foo='bar'; -- shows the called triggers

Depois, há uma coisa que eu não sabia antes: só dispara fogo ao atualizar a tabela exata que está definido no. Se você usar a herança, você deve defini-los nas tabelas filho também!

Respondeu 23/11/2008 em 20:45
fonte usuário

votos
42

  1. Use o seguinte código dentro de uma função de gatilho, em seguida, assistir a guia 'mensagens' em pgadmin3 ou a saída em psql:

    RAISE NOTICE 'myplpgsqlval is currently %', myplpgsqlval;       -- either this
    RAISE EXCEPTION 'failed';  -- or that
    
  2. Para ver o que desencadeia na verdade são chamados, quantas vezes etc, a seguinte declaração é o salva-vidas de escolha:

    EXPLAIN ANALYZE UPDATE table SET foo='bar'; -- shows the called triggers
    

    Note-se que se o seu disparo não está sendo chamado e você usar a herança, pode ser que você só tenha definido um gatilho na tabela pai, enquanto triggers não são herdadas por tabelas filho automaticamente.

  3. Para percorrer a função, você pode usar o depurador incorporado pgadmin3, que no Windows é ativado por padrão; tudo que você tem a fazer é executar o código encontrado em ... \ 8.3 \ share \ contrib \ pldbgapi.sql contra o banco de dados você está depurando, reinicie pgadmin3, clique com o botão direito sua função de gatilho, hit 'Set Breakpoint', e em seguida executar uma instrução que faria com que o gatilho para disparar, como a instrução UPDATE acima.

Respondeu 09/01/2009 em 23:55
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more