streams trigger

panys 2008-12-31 03:56:09
把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;
...全文
174 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
yun222222 2009-01-22
  • 打赏
  • 举报
回复
学习了没用过STREAM
watson110 2009-01-22
  • 打赏
  • 举报
回复
这样是取不到数据的,除非你自己建立规则
panys 2009-01-14
  • 打赏
  • 举报
回复
还是没有答案,好吧,我把需求在说清楚点,现有三个DB(db_A,db_B,db_C),各有一个表T1。db_A和_dbC中的数据可以通过Streams同步到db_B中,此时数据同步到db_B后是不用做任何处理的。

但如果在db_B端手工地插入一条数据时,我们则需要根据一些业务分类,分别把这样的数据传回到db_A或db_C中。所以此时在db_B的T1中要能够区分这条数据的来源是:1 Streams同步过来的,还是2 db_B来身产生的。(db_B相当是一个所有DB数据的全集)

目前,我们能根据user为空认定它是1 Streams同步过来的,否则是2 db_B来身产生的。但这种判断为空的作法不严谨,只是试验出来的,我是想确切地知道,是不是对于1就是不能得到user的值,还是说某个地方设的不对?
BlueskyWide 2009-01-14
  • 打赏
  • 举报
回复
Streams以前没用到过。

能否在所有的T1表中增加一个字段User_From,
当update,insert t1表(使用Trigger)时,自动写入User_From字段,以此可以判断来自于何User。

关键是:1.没有解决根本问题;2.T1此类的表多时,以上方法并不合适。

是否可以考虑使用Package。
panys 2009-01-13
  • 打赏
  • 举报
回复
谢谢,BlueskyWide,你可能有些误会了。
为了让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值。
BlueskyWide 2009-01-10
  • 打赏
  • 举报
回复
查了一下:
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;


zengxiaodonghc 2009-01-07
  • 打赏
  • 举报
回复
飘过
Andy__Huang 2009-01-07
  • 打赏
  • 举报
回复
黄别好久才出来一次...
panys 2009-01-07
  • 打赏
  • 举报
回复
试过了,ora_login_user同USER一样都为空,同时试了ora_client_ip_address也为空。
但ora_database_name和ora_instance_num都是能得到的。

难道streams过来的数据,都通过自已的渠道,而不产生user,ora_login_user,ora_client_ip_address吗?
ab5669 2009-01-07
  • 打赏
  • 举报
回复
改成这样试下:
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系统函数
oraclelogan 2009-01-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 panys 的回复:]
谢谢,BlueskyWide。

哦,情况是这样的,由于对系统的高可用性要求比较高,我们用streams是必须的,是基本前提条件,所有的业务都是基于streams基础上来开展的,现在遇到的是其中的一个技术问题:
通过streams同步过来的数据,为何在目标端db的表trigger中无法读取到user变量的值?
[/Quote]

学习了,以前没有碰到过类似问题!
oraclelogan 2009-01-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 panys 的回复:]
谢谢,BlueskyWide。

哦,情况是这样的,由于对系统的高可用性要求比较高,我们用streams是必须的,是基本前提条件,所有的业务都是基于streams基础上来开展的,现在遇到的是其中的一个技术问题:
通过streams同步过来的数据,为何在目标端db的表trigger中无法读取到user变量的值?
[/Quote]

学习了,以前没有碰到过类似问题!
panys 2009-01-04
  • 打赏
  • 举报
回复
谢谢,BlueskyWide。

哦,情况是这样的,由于对系统的高可用性要求比较高,我们用streams是必须的,是基本前提条件,所有的业务都是基于streams基础上来开展的,现在遇到的是其中的一个技术问题:
通过streams同步过来的数据,为何在目标端db的表trigger中无法读取到user变量的值?

BlueskyWide 2009-01-04
  • 打赏
  • 举报
回复
如果db1.A和db2.A在相同的服务器上,仅需要在user2下:select * from user1.A;
如果db1.A和db2.A在不同的服务器上,则建立db_link1后,在user2下:select * from A@db_link1;
BlueskyWide 2009-01-04
  • 打赏
  • 举报
回复
可以换一种思维来实现:
1.以sysdba用户创建同义词(synonym);
2.conn user2/pwd2@str2;
create table test as select * from user1.test where 1=1;
3.如果实时性较强,可以制作一下脚本,将上述过程写入一个存贮过程中。使用JOB,每5分钟执行一次。

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧