问题描述
嗨,汤姆,
我有一个触发器脚本,需要为一个表执行该表,该表的列会根据插件的更改而不断变化。一旦我们假设我们的表 () 中有新列,我需要开发一个触发器来捕获该表上的DML操作,其中有警报列。我已经编写了以下触发器脚本,该脚本已成功编译,但未在CDC中插入任何条目 (更改数据捕获表) :-
你能帮我一下我在这里做错了什么吗?
我有一个触发器脚本,需要为一个表执行该表,该表的列会根据插件的更改而不断变化。一旦我们假设我们的表 () 中有新列,我需要开发一个触发器来捕获该表上的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更改时被触发,然后动态地重新生成 * 触发器 *,以便触发器具有静态代码而不是动态代码。
我认为这将是一种比这更好的方法。
也许一个更好的主意是有一个数据库级触发器,当你对表进行DDL更改时被触发,然后动态地重新生成 * 触发器 *,以便触发器具有静态代码而不是动态代码。
我认为这将是一种比这更好的方法。
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




