我现在做的一个系统分为内外网,要必须物理隔离,所以必须进行数据交互。因此,内外网数据库结构相同,都有可能进行数据修改操作。此时如果进行内外网的数据交互时,就要考虑同步的问题。我设计了一个表sys_RecordChangeLog,专门用来记录所有表的记录修改过程,给每个表建三个触发器:INSERT UPDATE DELETE,然后生成操作的SQL语句,保存在sys_RecordChangeLog中。但我不想为每个表都写一遍触发器代码,而是想通过一个通用的函数实现。以下是我的想法:create or replace trigger trg_update_Table1
before Update on table1
for each rowdeclare
sSQL varchar2(30000);begin
:new.Version:=nvl(:old.Version,0)+1; sSQL :='Update table1 set '; for rdField in (select column_Name from user_tab_cols where tablename='Table1') loop
if :old.(字段名rdField.column_name)<>:new.(字段名rdField.column_name) then
sSQL :=sSQL ||' '||rdField.column_name||'='||:new.(字段名rdField.column_name)||',';
end if;
end loop; sSQL:=sSQL||' where ID='||:old.ID;
end trg_update_Table1;Oracle中有这样的用法吗?或者给一个更好的解决方案!谢谢!
before Update on table1
for each rowdeclare
sSQL varchar2(30000);begin
:new.Version:=nvl(:old.Version,0)+1; sSQL :='Update table1 set '; for rdField in (select column_Name from user_tab_cols where tablename='Table1') loop
if :old.(字段名rdField.column_name)<>:new.(字段名rdField.column_name) then
sSQL :=sSQL ||' '||rdField.column_name||'='||:new.(字段名rdField.column_name)||',';
end if;
end loop; sSQL:=sSQL||' where ID='||:old.ID;
end trg_update_Table1;Oracle中有这样的用法吗?或者给一个更好的解决方案!谢谢!
0代表改条数据没有更新过,1代表更新过.数据交换时,只把标记为1的数据更新到内网的库的各表,交换完毕后,把标记更新为0.
这个我一直很郁闷
还是不清楚!!
想法是好的,不过好像Oracle无法用这样的方式实现。
实现起来比较复杂
create or replace trigger trigger_CLXX
before INSERT OR UPDATE OR DELETE on wsba.hx_a_clxx
for each row
-- local variables here
DECLARE
CURCHGCOL VARCHAR2(30);
CHGCOL VARCHAR2(1000);
CHGCOLVALUE CLOB;
TEMP1 VARCHAR(30);
TEMP2 VARCHAR(30);
EQUALS varchar(1);
STRSQL varchar(300);
begin
-- query all colnames
-- get changed colnames and values
FOR j IN (select COLUMN_NAME from user_tab_columns where upper(Table_name) = upper('HX_A_CLXX') AND DATA_TYPE NOT IN('CBLOB','BLOB','NCLOB','BFILE')) Loop
CURCHGCOL:=j.COLUMN_NAME;
TEMP1:=':old.'||CURCHGCOL;
TEMP2:=':new.'||CURCHGCOL;
-- TEMP1:=CURCHGCOL;
-- TEMP2:=CURCHGCOL;
STRSQL:='SELECT case when '||TEMP1||'='||TEMP2||' then "1" else "0" end from dual ';
execute immediate STRSQL into EQUALS;
IF(EQUALS<>'1') THEN
CHGCOL:=CONCAT(CHGCOL,CONCAT(CURCHGCOL,','));
CHGCOLVALUE:=CONCAT(CHGCOLVALUE,CONCAT(TEMP2,','));
END IF;
END LOOP;
CHGCOL:=SUBSTR(CHGCOL,1,LENGTH(CHGCOL)-1);
CHGCOLVALUE:=SUBSTR(CHGCOLVALUE,1,LENGTH(CHGCOLVALUE)-1);
IF INSERTING THEN
-- when insert into table
insert into GX_LS_LSXX(guid,MSM,BM,BL,BLZ,LRRYBH,LRRYMC,LRRYJH,LRRYBMBH,LRRYBMMC,LRSJ)
values (sys_guid(),'WSBA','HX_A_CLXX',CHGCOL,CHGCOLVALUE,:new.LRRYBH,:new.LRRYMC,:new.LRRYJH,:new.LRRYBMBH,:new.LRRYBMMC,:new.LRSJ);
ELSIF UPDATING THEN
-- when update table values
insert into GX_LS_LSXX(guid,MSM,BM,BL,BLZ,LRRYBH,LRRYMC,LRRYJH,LRRYBMBH,LRRYBMMC,LRSJ)
values (sys_guid(),'WSBA','HX_A_CLXX',CHGCOL,CHGCOLVALUE,:new.LRRYBH,:new.LRRYMC,:new.LRRYJH,:new.LRRYBMBH,:new.LRRYBMMC,:new.LRSJ);
ELSE
insert into GX_LS_LSXX(guid,MSM,BM,BL,BLZ,LRRYBH,LRRYMC,LRRYJH,LRRYBMBH,LRRYBMMC,LRSJ)
values (sys_guid(),'WSBA','HX_A_CLXX',CHGCOL,CHGCOLVALUE,:old.LRRYBH,:old.LRRYMC,:old.LRRYJH,:old.LRRYBMBH,:old.LRRYBMMC,:old.LRSJ);
END IF;
end trigger_CLXX;
上面的做法可以成功创建触发器,但是总是在触发时提示变量不能绑定(在oracle10g测试)
v_sql = 'select fun_str_replace(:new.id) from dual';
execute IMMEDIATE v_sql INTO INTO v_id ;