Hi I am trying to create a log of changes in a table by using oracle triggers
The log table consist of the ,time of action ,tablename,actiontype and xmldata (clob)
Iam trying to convert the new row to xml and save it as xmldata
create or replace TRIGGER EVAL_CHANGE_TriggerActual_DYNAMIC
AFTER INSERT OR UPDATE OR DELETE
ON PROJ_TEST
REFERENCING NEW AS new OLD AS old
FOR EACH ROW
DECLARE
log_action varchar(10);
p_xmldata XMLtype;
P_NEWROWDATA clob;
p_newrowxml clob;
BEGIN
select rtrim(xmlelementcol,',') into p_newrowxml from ( Select LISTAGG(str, '') as xmlelementcol from (select 'XMLElement("'||cols.column_Name||'", :NEW.'||cols.column_name||'),' as str
from SYS.ALL_TAB_COLS cols where upper(cols.owner)=upper('DEV_CUSTOM') and upper(cols.table_name)=upper('PROJ_TEST') order by column_id ));
p_newrowxml:=CONCAT('select XMLElement("ResearchTable",',p_newrowxml);
p_newrowxml:=CONCAT(p_newrowxml,')from dual');
DBMS_OUTPUT.PUT_LINE(p_newrowxml);
EXECUTE IMMEDIATE p_newrowxml into p_xmldata;
p_newrowdata:=p_xmldata.getClobVal();
IF INSERTING THEN
log_action := 'Insert';
ELSIF UPDATING THEN
log_action := 'Update';
ELSIF DELETING THEN
log_action := 'Delete';
ELSE
DBMS_OUTPUT.PUT_LINE('This code is not reachable.');
END IF;
INSERT INTO audits(table_name, transaction_name, by_user, transaction_date,xmldata,TRIGGERNAMEdesc)
VALUES('PROJ_TEST', log_action, USER, SYSDATE,p_newrowdata,'EVAL_CHANGE_TriggerDynamic');
END;
Now if If i remove the below code
'XMLElement("'||cols.column_Name||'", :NEW.'||cols.column_name||'),'
to
'XMLElement("'||cols.column_Name||'", 1),'
Its working otherwise not thowing error at EXECUTE IMMEDIATE. Can any one help
while my first answer works, it would depend heavily on table-columns, not really usable if many tables have to be audited. Based on a comment from @Sayan Malakshinov and the linked artikle StevenFeuerstein&CompoundTrigger. the final audit-loop might cause performance-trouble if many rows are processed in one update .... mass-update could be moved to a more optimized update-compound-trigger writing all update-rows with one single "insert into tblaudit() select auditColumns from tblone where id in (recorded id´s)"
In case update with many-rows have really to be considered: