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
