简体   繁体   English

在使用 Merge Insert Update 作为增量策略的表上触发

[英]Trigger on a table that uses Merge Insert Update as Incremental strategy

  • 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.有问题的触发器适用于在 ODI 中具有 ETL 的表,但用户也可以选择编辑某些 **列 **(如果他们想要调整它们)。 This is done using APEX这是使用APEX完成的
  • Trigger is used to change two columns: Changed_by and Change_on .触发器用于更改两列: Changed_byChange_on Both indicating Changes done on APEX PAGE only.两者都表示仅在 APEX 页面上完成的更改。
  • 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.当运行 ODI 加载并且是 MERGE INSERT UPDATE 时,问题就出现了,Trigger 认为它正在更新并将以上两列更改为“NULL”,因为它是由 ODI 而不是在 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.对于每个可编辑列,应该有一个检查 NEW:<>:OLD 的逻辑,但因为我有 15 列需要编写大量代码。

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;

Check if an apex session exists for the current database session and only execute when it is the case.检查当前数据库 session 是否存在顶点 session,只有在存在时才执行。

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.避免SELECT FROM DUAL ,您只需在触发器中分配值即可。
  • The "V" functions are pretty slow. “V”功能非常慢。 For a while there have been sys_context settings that store the session and user data.一段时间以来,存在存储 session 和用户数据的 sys_context 设置。 Those are a lot faster than a function call to the "V" function.这些比 function 调用“V”function 快得多。

You could make it so that it never overwrites a non-null value with a null one:你可以让它永远不会用 null 覆盖一个非空值:

IF v('APP_USER') IS NOT NULL
THEN
  :new.changed_by := v('APP_USER');
  :new.changed_on_dt := SYSDATE;
END IF;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM