Aff... Top-posting bagunça tudo mesmo...

2013/1/9 Marcelo Silva <[email protected]>

>   Hum,
>
> Vou estudar esse cara,
>
> Obrigado...
>
>
>
>  *From:* Matheus de Oliveira <[email protected]>
> *Sent:* Wednesday, January 09, 2013 11:32 AM
> *To:* Comunidade PostgreSQL Brasileira<[email protected]>
> *Subject:* Re: [pgbr-geral] Trigger de alterações
>
>
>
> 2013/1/9 Marcelo Silva <[email protected]>
>
>>   Hum,
>>
>> Eu já fiz isso em Firebird, nele temos como percorrer os campos de uma
>> tabela com um FOR,
>> dessa forma se a tabela é alterada ( acrescentando ou retirando uma campo
>> ) a trigger continua funcional.
>> Fazendo campo a campo, toda vez que a tabela é alterada tenho que refazer
>> a trigger... isso será trabalhoso.
>>
>> Quando um registro é alterado o AfterPost não leria o registro
>> posicionado ?
>>
>> Será que não consigo fazer um
>> FOR i=0 to FieldsCount
>> ou um
>> FOREACH FIELDS
>> no Postgres ?
>>
>> Então eu teria
>>
>> Valor = FIELDS[i].NEW
>>
>> Sabe aquele canivete suíço [image: Alegre]
>>
>>
>
> Dá sim, mas tem que usar HSTORE [1] ou uma linguagem que aceita isso. Ou
> ainda a trigger after e um select dinâmico.
>
> [1] http://www.postgresql.org/docs/current/static/hstore.html
>
>
Cara, montei um exemplo pra mostrar o uso do HSTORE com PL/pgSQL, o que
ajuda muito para fazer esse tipo de trigger genérica:

CREATE TABLE audit (
    schema_name text,
    table_name text,
    datetime timestamptz,
    type char(1),
    username text,
    fields hstore
);

CREATE OR REPLACE FUNCTION public.tg_audit()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$
DECLARE
        v_new text[];
        v_old text[];
        v_fields hstore;
BEGIN
    CASE TG_OP
    WHEN 'INSERT' THEN
        v_fields = hstore(NEW);
    WHEN 'UPDATE' THEN
        v_fields = hstore(array[]::text[]);
        v_new = hstore_to_matrix(hstore(NEW));
        v_old = hstore_to_matrix(hstore(OLD));
        FOR i IN 1..array_upper(v_new, 1) LOOP
                RAISE NOTICE 'Value of % is %', v_new[i][1], v_new[i][2];
                IF (v_new[i][2] <> v_old[i][2]) THEN
                    v_fields = v_fields || hstore(v_new[i][1], v_new[i][2]);
                END IF;
        END LOOP;
    WHEN 'DELETE' THEN
        v_fields = null;
    END CASE;
    INSERT INTO audit(schema_name, table_name, datetime, type, username,
fields)
    VALUES(TG_TABLE_SCHEMA, TG_TABLE_NAME, now(), substr(TG_OP, 1, 1),
current_user, v_fields);
    RETURN NULL;
END;
$function$;

CREATE TRIGGER tg_audit
AFTER INSERT OR DELETE OR UPDATE ON test
FOR EACH ROW EXECUTE PROCEDURE tg_audit();


Essa trigger serve tanto para UPDATE, DELETE ou INSERT. Ela insere na
tabela audit em um campo do tipo HSTORE, apenas aqueles campos que foram
alterados, no caso de UPDATE. Para INSERT, insere tudo e para DELETE insere
NULL.

Espero que ajude.


Atenciosamente,
-- 
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres

<<wlEmoticon-smile[1].png>>

_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a