- Trigger under question is for Table which has ETL in ODI but user also has option to edit certain **columns ** if they want to adjust them. This is done using APEX
- Trigger is used to change two columns : Changed_by and Change_on. Both indicating Changes done on APEX PAGE only.
- The issue comes when ODI load is run and is MERGE INSERT UPDATE , Trigger thinks its updating and changes the above two columns to "NULL" as its a manual update done by ODI and not on APEX.
Solution
- For each Editable Column, there should be a logic which checks NEW: <> :OLD, but as i have 15 columns need to write a lot of code.
Are there others way to achieve this ?
create or replace TRIGGER DW.TRG BEFORE
UPDATE ON DW.TABLE
REFERENCING
NEW AS new
OLD AS old
FOR EACH ROW
BEGIN
IF updating THEN
SELECT
SYSDATE,
v('APP_USER')
INTO
:new.changed_on_dt,
:new.changed_by
FROM
dual;
END IF;
END;
CodePudding user response:
Check if an apex session exists for the current database session and only execute when it is the case.
create or replace TRIGGER DW.TRG BEFORE
UPDATE ON DW.TABLE
REFERENCING
NEW AS new
OLD AS old
FOR EACH ROW
BEGIN
IF SYS_CONTEXT('APEX$SESSION','APP_SESSION') IS NOT NULL AND updating THEN
:new.changed_on_dt := SYSDATE;
:new.changed_by := SYS_CONTEXT('APEX$SESSION','APP_USER');
END IF;
END;
Notes
- avoid the
SELECT FROM DUAL
, you can just assign the values in the trigger. - The "V" functions are pretty slow. For a while there have been sys_context settings that store the session and user data. Those are a lot faster than a function call to the "V" function.
CodePudding user response:
You could make it so that it never overwrites a non-null value with a null one:
IF v('APP_USER') IS NOT NULL
THEN
:new.changed_by := v('APP_USER');
:new.changed_on_dt := SYSDATE;
END IF;