Fórum Trigger para pegar somente o que foi modificado no registro #429939
28/11/2012
0
[url]http://www.postgresql.org/docs/9.0/static/plpgsql-trigger.html#PLPGSQL-TRIGGER-AUDIT-EXAMPLE[/url]
Como posso fazer pra pegar somente o que foi modificado? utilizando esse exemplo.
Paulo Pinto
Curtir tópico
+ 0Posts
28/11/2012
Paulo Pinto
CREATE OR REPLACE FUNCTION process_emp_audit()
RETURNS trigger AS
$BODY$
BEGIN
--
-- Create a row in emp_audit to reflect the operation performed on emp,
-- make use of the special variable TG_OP to work out the operation.
--
IF (TG_OP = 'DELETE') THEN
INSERT INTO logs SELECT now(), TG_OP, TG_TABLE_NAME, cast('Registro Antigo '||OLD.* as text) ;
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
--> AQUI PEGAR SOMENTE O QUE FOI MODIFICADO...
--> OU COM UM FOR, SABER O NOME DA COLUNA PRA FICA LADO A LADO
--> Exemplo:
--> Coluna Modificada | Registro Antigo | Registro Novo
--> pess_nome | Paulo | Paulo Alexandre
INSERT INTO logs SELECT now(), TG_OP, TG_TABLE_NAME, cast('Registro Antigo '||OLD.* ||' Novo Registro '||OLD.* as text) ;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
-- INSERT INTO logs SELECT null, null, TG_OP, TG_TABLE_NAME, 0, 0, cast(NEW.* as text) ;
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Gostei + 0
28/11/2012
Jair N.
Antes: ARRAY_TO_STRING(ARRAY[OLD], '|')
para pegar campo a campo use a exemplo o sequencial dos campos e o nome Exemplo:
SELECT pg_attribute.attnum
, pg_attribute.attname
FROM pg_attribute
INNER JOIN pg_type
ON (pg_type.typrelid = pg_attribute.attrelid)
WHERE (pg_type.typname = "TG_RELNAME") -- nome da tabela para pesquisa
AND (pg_attribute.attstattarget = -1)
Bem, eu não descobri outra maneira de validar o que foi mudado sem fazer um processo de comparação entre o antes e o agora... Outra veja a necessidade de guardar os nomes dos campos, pois a tabela pode mudar conforme novas implementações.
Atc.
CREATE OR REPLACE FUNCTION process_emp_audit()
RETURNS trigger AS
$BODY$
BEGIN
--
-- Create a row in emp_audit to reflect the operation performed on emp,
-- make use of the special variable TG_OP to work out the operation.
--
IF (TG_OP = 'DELETE') THEN
INSERT INTO logs SELECT now(), TG_OP, TG_TABLE_NAME, cast('Registro Antigo '||OLD.* as text) ;
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
--> AQUI PEGAR SOMENTE O QUE FOI MODIFICADO...
--> OU COM UM FOR, SABER O NOME DA COLUNA PRA FICA LADO A LADO
--> Exemplo:
--> Coluna Modificada | Registro Antigo | Registro Novo
--> pess_nome | Paulo | Paulo Alexandre
INSERT INTO logs SELECT now(), TG_OP, TG_TABLE_NAME, cast('Registro Antigo '||OLD.* ||' Novo Registro '||OLD.* as text) ;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
-- INSERT INTO logs SELECT null, null, TG_OP, TG_TABLE_NAME, 0, 0, cast(NEW.* as text) ;
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Gostei + 0
28/11/2012
Paulo Pinto
mas minha conversão do registro para ARRAY tem uma "Adaptação técnica" rsrs
tem outro jeito de converter isso?
CREATE OR REPLACE FUNCTION process_emp_audit()
RETURNS trigger AS
$BODY$
DECLARE
rec RECORD;
textolog text;
Antes varchar array;
Depois varchar array;
nomecampo varchar;
nomescampos varchar array;
i integer;
texto text;
BEGIN
textolog = '';
i = 0;
--
-- Create a row in emp_audit to reflect the operation performed on emp,
-- make use of the special variable TG_OP to work out the operation.
--
IF (TG_OP = 'DELETE') THEN
INSERT INTO logs SELECT 0, now(), TG_OP, TG_TABLE_NAME, 0, 0, cast('Registro Antigo '||OLD.* as text) ;
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
--> AQUI PEGAR SOMENTE O QUE FOI MODIFICADO...
--> OU COM UM FOR, SABER O NOME DA COLUNA PRA FICA LADO A LADO
--> Exemplo:
--> Coluna Modificada | Registro Antigo | Registro Novo
--> pess_nome | Paulo | Paulo Alexandre
textolog = 'Coluna Modificada | Registro Antigo | Registro Novo\n';
---------------------ADAPTAÇÃO TÉCNICA -------------------------------
texto = cast(OLD as text);
texto = substr(texto,2 ,length(texto)-2);
Antes = string_to_array(texto,',');
texto = cast(NEW as text);
texto = substr(texto,2 ,length(texto)-2);
Depois = string_to_array(texto,',');
----------------------------------------------------------------------
nomescampos = ARRAY(select attname FROM pg_attribute WHERE attrelid = TG_RELID AND attstattarget = -1 order by attnum);
for i in 1..array_length(nomescampos, 1)
LOOP
IF Antes[i] <> Depois[i] THEN
textolog = textolog||nomescampos[i]||'|'||Antes[i]||'|'||Depois[i]||'\n';
END IF;
END LOOP;
INSERT INTO logs SELECT 0, now(), TG_OP, TG_TABLE_NAME, 0, 0, textolog ;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
-- INSERT INTO logs SELECT null, null, TG_OP, TG_TABLE_NAME, 0, 0, cast(NEW.* as text) ;
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Gostei + 0
31/07/2013
José
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)