• 用触发器实现数据关联修改


    一、前言

    我所在的公司,有的人数据库设计喜欢冗余字段,比如订单中需要存储客户,一般我们只放客户id,但是他不,要把客户名称冗余进去。如果后期来客户名称更改了,这里是需要改过来的。如果用程序来实现同步修改的话,hi比较麻烦。与有的人不喜欢用触发器和存储过程相反,我喜欢用触发器来做这类简单粗暴的事情,简单又不失优雅。N年前,我曾经用存储过程实现过一个接口系统,当时未解决sql server 存储过程递归调用不能超过9层大伤脑筋。这是闲话,下面我们来讲怎么用触发器实现数据的关联修改。

    二、配置表

    要实现关联修改,首先要知道哪些表引用了哪些表,也就是表与表之间的引用关系,比如上面呢的例子,订单表引用了客户表。这个需要通过一个配置表进行定义。配置表的结构如下:

    数据引用关系表:phs_dataref_rel
      说明
    1 table_name   引用其他表数据的表的名称,比如上面的订单表
    2 fk_col 外键列名称,比如订单中的客户id列
    3 fk_name_col   引用数据的名称列,比如订单中的客户名称列
    4 fkref_table   引用的表名称,比如上例中的客户表      
    5 cond_expr 修改的附件条件,比如只修改当年的数据,历史年度的维持不动
    6 enable 本条配置是否生效,可以修改为0,不启用本条配置

    举个例子:

    insert into phs_dateref_rel( table_name, fk_col, fk_name_col fkref_table ) values( 'sd_order', 'cust_id', 'cust_name', 'md_customer' );

    以上的配置信息,定义了 sd_order 订单表的 cust_id 引用了 md_customer 客户表 的id,cust_name 是客户的名称。(本文只处理 id-name 这种简单的引用关系,其他的雷同)。

    三、触发器

    我们在md_customer上实现一个触发器,当客户名称修改时,同步修改订单表中的客户名称。

     1 create or replace trigger tri_update_ref_name
     2 after update on md_customer
     3 for each row
     4 declare
     5   v$sql varchar2(1000) ;
     6 begin
     7    if updating( 'name') then
     8       for r in( select table_name,fk_col, fk_name_col, cond_expr from phs_fkref_relation where UPPER(fkref_table) = 'MD_CUSTOMER') loop
     9          v$sql :='update '|| r.table_name ||' set '||r.fk_name_col||' =:1 where '||r.fk_col||' = :2';

      10          if ( trim( r.cond_expr ) is not null ) then
      11            v$sql := v$sql + ' and ' || trim( r.cond_expr) ;
      12          1end if ;

    13          execute immediate v$sql using :new.name, :new.id;
    14       end loop;
    15    end if ;
    16 end ;

    以上触发器的功能是,当客户名称修改时,他会根据配置表,查找所有引用客户名称的表,将表中的客户名称列的值修改为新的值。

    四、总结

    以上方案实现了,通过触发器修改关联的数据。比较适合的场景是:

    存在大量的这种冗余数据,尤其是历史遗留项目,如果通过代码避免这种冗余或实现同步修改会关联数据,付出大量的成本。

    局限:

    以上方案只处理了通过id-name这种形式,冗余name这种情况。但是举一反三,通过扩展,他也可以期限其他冗余数据的级联更新,比如客户联系信息等等。

    其实解决数据不一致的根本举措还是避免滥用冗余,使用冗余要有原则。文中的方案只是一种外挂式的备选方案。

  • 相关阅读:
    02方法 课后作业1
    HDU 1518
    POJ 2406
    HDU 1953
    HDU 1272
    POJ -- 3842
    POJ -- 3233 求“等比矩阵”前n(n <=10^9)项和
    POJ ---3070 (矩阵乘法求Fibonacci 数列)
    POJ --- 3613 (K步最短路+矩阵快速幂+floyd)
    POJ --- 2918 求解数独
  • 原文地址:https://www.cnblogs.com/senline/p/update_refdata_by_trigger.html
Copyright © 2020-2023  润新知