Oracle两张数据表之间某个指定字段的单向和双向同步

1、单向同步:

大致介绍:ceshione这张表中的AA字段发生改变,ceshitwo这张表中如果存关联id则CC字段改成相同的值;而ceshitwo这张表中的CC字段发生改变,就算ceshione这张表中存在关联id,AA字段也不发生改变!

用途:主要用于主表与从表之间,以主表为准的情况!

实现代码如下:

1.ceshione表:

CREATE TABLE "MZD"."CESHIONE" (
"AA" VARCHAR2(255 BYTE) NULL ,
"BB" VARCHAR2(255 BYTE) NULL ,
"ID" NUMBER NULL 
)

2.ceshitwo表:

CREATE TABLE "MZD"."CESHITWO" (
"CC" VARCHAR2(255 BYTE) NULL ,
"DD" VARCHAR2(255 BYTE) NULL ,
"ID" NUMBER NULL 
)

3.单向同步脚本:

create or replace trigger tongbu
    after insert or update or delete
    on CESHIONE
    referencing old as old_value
                new as new_value
    for each row
begin
    if inserting then
     update CESHITWO set CC = :new_value.AA
      where id = :new_value.id;
    elsif updating then
     update CESHITWO set CC = :new_value.AA
      where id = :new_value.id;
    end if;
end;

2、双向同步:

大致介绍:ceshione这张表中的AA字段发生改变,ceshitwo这张表中如果存关联id则CC字段改成相同的值;相同,ceshitwo这张表中的CC字段发生改变,ceshione这张表中如果存关联id则AA字段改成相同的值。

用途:主要用于两张级别相同的表中,还有一种可能是,设计数据库的时候没有设计好,出现相同的字段在不同的表中出现不同的值!!!

是不是会有脑洞大开的人-再写一个触发器,让ceshitwo中的CC发生改变的时候ceshione中的AA也发生改变

然后就变成这样:

这里写图片描述

这里写图片描述

正确的实现方案:

两张表上分别建立触发器进行同步,但是这样操作会有个问题,就会导致触发器循环触发。那么就需要在触发器进行触发前,进行一个判断,如果操作是由触发器引发的,那么就不做操作,反之,执行触发器定义的操作。想要实现这个,我开始考虑过在触发器a里面暂时使触发器b失效,但是发现alter trigger disable不合法;然后看到有人提到在表里面新增一个字段,用来做标识,但是这样需要修改表结构,虽然可以达到要求,但是总觉得不是很好,所以也没有使用;后来通过学习oracle对象,了解到了包的特性,所以决定采用包的方式来实现,利用包的变量来做标识。

参考网址:

https://www.thinksaas.cn/group/topic/468345/

代码实现:

1.ceshione表:

CREATE TABLE "MZD"."CESHIONE" (
"AA" VARCHAR2(255 BYTE) NULL ,
"BB" VARCHAR2(255 BYTE) NULL ,
"ID" NUMBER NULL 
)

2.ceshitwo表:

CREATE TABLE "MZD"."CESHITWO" (
"CC" VARCHAR2(255 BYTE) NULL ,
"DD" VARCHAR2(255 BYTE) NULL ,
"ID" NUMBER NULL 
)

3.双向同步脚本:

(1)这部分不需要改—作为一只菜鸟,没看的太明白0.0

--创建包头
create or replace package pk_check_active is 
  --标识是否为触发器引发
  n number :=0;
  --获取是否为触发器触发标识,1为触发器触发
  function getactive return number;
  --设置状态
  procedure setactive(n1 in number);
end pk_check_active;

create or replace package body pk_check_active as
  function getactive return number is
  begin
    return n;
  end getactive;
  procedure setactive(n1 in number) is
  begin
    n := n1;
  end setactive;
end pk_check_active;

(2)触发表CESHIONE:

create or replace trigger tr_cs_user after insert or update
on CESHIONE for each row
begin
   if pk_check_active.getactive() =1 then
     pk_check_active.setactive(2);  return;
    else
     pk_check_active.setactive(1);
   end if;
if inserting then
   update CESHITWO  set CESHITWO.CC=:new.AA WHERE CESHITWO.ID=:NEW.ID;
elsif updating then 
    update CESHITWO  set CESHITWO.CC=:new.AA WHERE CESHITWO.ID=:NEW.ID;
end if;
    pk_check_active.setactive(0);
end;

(3)触发表CESHITWO:

create or replace trigger tr_bs_user after insert or update
on CESHITWO for each row   
begin
 if pk_check_active.getactive() =1 then
     pk_check_active.setactive(2); return;
 else
     pk_check_active.setactive(1);
 end if;
if inserting then
 update CESHIONE  set CESHIONE.AA=:new.CC where CESHIONE.ID=:NEW.ID;
elsif updating then 
        update CESHIONE  set CESHIONE.AA=:new.CC where CESHIONE.ID=:NEW.ID;
end if;
     pk_check_active.setactive(0);
end;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值