暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 触发器内部的动态查询

ASKTOM 2019-05-02
241

问题描述

嗨,汤姆,
我有一个触发器脚本,需要为一个表执行该表,该表的列会根据插件的更改而不断变化。一旦我们假设我们的表 () 中有新列,我需要开发一个触发器来捕获该表上的DML操作,其中有警报列。我已经编写了以下触发器脚本,该脚本已成功编译,但未在CDC中插入任何条目 (更改数据捕获表) :-

CREATE OR REPLACE TRIGGER TCDC_TG_Table1
BEFORE    
INSERT ON Table1  
REFERENCING            
OLD AS old    NEW AS new    
FOR EACH ROW
DECLARE
    old_col_value   VARCHAR2(4000) default null;
    new_col_value   VARCHAR2(4000) default null;
    t_type          VARCHAR(1);
    t_dcid          NUMBER(10, 0);
    t_alertname     VARCHAR(30);
    lv_query        VARCHAR(500);
    lv_col          VARCHAR(50);
PRAGMA AUTONOMOUS_TRANSACTION; 
BEGIN
    t_type := NULL;
    FOR rec IN (SELECT t.column_name FROM all_tab_cols t WHERE t.table_name = 'TABLE1' AND t.column_name LIKE '%IS%') LOOP
        lv_col := rec.column_name;
        lv_query := 'select :old.'|| lv_col || ', :new.'|| lv_col|| ' from dual';
  
  
        EXECUTE IMMEDIATE lv_query INTO old_col_value,new_col_value;
  T_ALERTNAME := REC.COLUMN_NAME;
  --old_col_value := :old.lv_col;
  --new_col_value := :new.lv_col;
        IF inserting AND new_col_value = 1 THEN
            t_type := 'I';
            t_dcid := :new.studentsdcid;
   
        END IF;
        IF updating THEN
            IF old_col_value = 1 AND nvl(new_col_value, 0) = 0 THEN
                t_type := 'D';
            ELSE
                IF nvl(old_col_value, 0) = 0 AND new_col_value = 1 THEN
                    t_type := 'U';
                END IF;
            END IF;
            t_dcid := :new.studentsdcid;
        END IF;
        IF deleting THEN
            t_type := 'D';
            t_dcid := :old.studentsdcid;
        END IF;
        IF t_type IS NOT NULL THEN
            INSERT INTO CDC (
                talend_cdc_subscribers_name,
                talend_cdc_state,
                talend_cdc_type,
                talend_cdc_creation_date,
                dcid,
                alertname
            ) VALUES (
                'STUDENTSALERTSUB',
                '0',
                t_type,
                systimestamp,
                t_dcid,
                t_alertname
            );
 commit;  
        END IF;
    END LOOP;
EXCEPTION
    WHEN OTHERS THEN
        NULL;
END;
复制


你能帮我一下我在这里做错了什么吗?

专家解答

我认为以这种方式解决问题是一个坏主意。运行效率低下。

也许一个更好的主意是有一个数据库级触发器,当你对表进行DDL更改时被触发,然后动态地重新生成 * 触发器 *,以便触发器具有静态代码而不是动态代码。

我认为这将是一种比这更好的方法。
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论