把db1.A表的数据通过streams同步到db2.A表中,db2.A中有一个trigger用于记录一些log信息,问题一是:当通过streams同步过来的数据,不会触发db2.A上的触发器,解决方法是在db2.A设置一下参数:
exec dbms_ddl.set_trigger_firing_property ('testuser', 'TR1_table_A', FALSE);
这个参数默认是true。设置好了,就可以触发db2.A上的触发器了。但问题二是:这个触发器里面的user值无法得到,但其它的如sysdate则正常。而且如果是手工地在db2.A中插入一条数据,则user值则能得到。请问各位,通过streams同步过来的数据,触发器里不能得到这个user值吗?这是db2.A上的触发器的SQL:
CREATE OR REPLACE TRIGGER TR1_table_A BEFORE UPDATE OR INSERT ON A FOR EACH ROW
BEGIN IF dbms_ddl.is_trigger_fire_once('dms', 'TR1_table_A') THEN
insert into test1 values('true', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
ELSE
insert into test1 values('false', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
END IF;
IF USER IS NULL THEN
insert into test2 values('USER IS NULL', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
ELSE
insert into test2 values(USER, to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
END IF;
END;
exec dbms_ddl.set_trigger_firing_property ('testuser', 'TR1_table_A', FALSE);
这个参数默认是true。设置好了,就可以触发db2.A上的触发器了。但问题二是:这个触发器里面的user值无法得到,但其它的如sysdate则正常。而且如果是手工地在db2.A中插入一条数据,则user值则能得到。请问各位,通过streams同步过来的数据,触发器里不能得到这个user值吗?这是db2.A上的触发器的SQL:
CREATE OR REPLACE TRIGGER TR1_table_A BEFORE UPDATE OR INSERT ON A FOR EACH ROW
BEGIN IF dbms_ddl.is_trigger_fire_once('dms', 'TR1_table_A') THEN
insert into test1 values('true', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
ELSE
insert into test1 values('false', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
END IF;
IF USER IS NULL THEN
insert into test2 values('USER IS NULL', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
ELSE
insert into test2 values(USER, to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
END IF;
END;
1.以sysdba用户创建同义词(synonym);
2.conn user2/pwd2@str2;
create table test as select * from user1.test where 1=1;
3.如果实时性较强,可以制作一下脚本,将上述过程写入一个存贮过程中。使用JOB,每5分钟执行一次。
如果db1.A和db2.A在不同的服务器上,则建立db_link1后,在user2下:select * from A@db_link1;
通过streams同步过来的数据,为何在目标端db的表trigger中无法读取到user变量的值?
CREATE OR REPLACE TRIGGER TR1_table_A BEFORE UPDATE OR INSERT ON A FOR EACH ROW
BEGIN IF dbms_ddl.is_trigger_fire_once('dms', 'TR1_table_A') THEN
insert into test1 values('true', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
ELSE
insert into test1 values('false', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
END IF; insert into test2 values(ora_login_user, to_char(sysdate,'DD/MM/YYYY HH24:MI:SS')); END;关键是用ora_login_user系统函数
但ora_database_name和ora_instance_num都是能得到的。难道streams过来的数据,都通过自已的渠道,而不产生user,ora_login_user,ora_client_ip_address吗?
IS_TRIGGER_FIRE_ONCE:检测特定的DML或DDL触发器是否只触发一次
语法:DBMS_DDL.IS_TRIGGER_FIRE_ONCE( trigger_owner IN VARCHAR2,--触发器所有者
trigger_name IN VARCHAR2--触发器名);
RETURN BOOLEAN;--返回为TRUE则表示触发器只被触发一次LZ在这里的引用{dbms_ddl.is_trigger_fire_once('dms', 'TR1_table_A')}可能有点问题:
dms是Oracle用户名吗?如果不是,那么引用错了;
如果是的话,可以试一下:
CREATE OR REPLACE TRIGGER TR1_table_A BEFORE UPDATE OR INSERT ON A FOR EACH ROW
BEGIN
IF dbms_ddl.is_trigger_fire_once('dms', 'TR1_table_A') THEN
insert into test1 values('dms', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
ELSE
insert into test1 values('', to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
END IF;
END;
为了让TRIGGER TR1_table_A BEFORE能够多次被触发,需要set_trigger_firing_property=false。
IF dbms_ddl.is_trigger_fire_once这句话在这里主要是做检测用的。关键点不在这里,可以忽略这段IF ...END IF。(dms是用户名)
重点是: insert into test2 values(ora_login_user, to_char(sysdate,'DD/MM/YYYY HH24:MI:SS'));
这句话里ora_login_user或者user无法得到当前用户值,目前总是null值。
当update,insert t1表(使用Trigger)时,自动写入User_From字段,以此可以判断来自于何User。关键是:1.没有解决根本问题;2.T1此类的表多时,以上方法并不合适。是否可以考虑使用Package。
http://www.di.unipi.it/~ghelli/didattica/bdl/B19306_01/server.102/b14228/rep_tags.htm#i1007476