zoukankan      html  css  js  c++  java
  • oracle有规律数据触发器实现递增(NC地区分类)|更新一路case简化|

    产品是用友NC财务软件,数据库是oracle
    产品端的情况如下:

    这是是地区分类,我们已经按照全国的地级市增加地区分类,然后需要在每个地级市增加有规律的12个分类,分包是:
    1  哈尔滨地材类供应商名录
    2  哈尔滨块材类供应商名录
    3  哈尔滨水泥类供应商名录
    4  哈尔滨木材类供应商名录
    5  哈尔滨金属类供应商名录
    6  哈尔滨高分子材料类供应商名录
    7  哈尔滨电工材料类供应商名录
    8  哈尔滨安全防护用品器材类供应商名录
    9  哈尔滨其他材料类供应商名录
    10 哈尔滨器材租赁供应商名录
    11 哈尔滨专业分包供应商名录
    12 哈尔滨税款、投标类他项名录
    这是oracle表的情况

    现在我们每次都要手工增加每个城市的12个分类,很麻烦。
    请问oracle有什么方法可以实现自动增加吗,增加需要根据每个城市,每个增加的项目的 bd_areacl.pk_areacl也需要是不同的,上一级是我们已经增加好的地级市。
    触发器?函数?
    谢谢大家
    6.10号更新:
    昨天和今天在我矿大计算机专业的同学们这里,问了几个人,初步有两个想法
    1,写触发器。
    在增加地级市第一类材料的时候,触发器里面写insert,一共写11个,名称分两部分,第一部分的地级市名字可以通过:new的name和substr搞定,然后后面的收工录入,比如增加“ 哈尔滨地材类供应商名录”保存之后,触发器自动完成
    2  哈尔滨块材类供应商名录
    3  哈尔滨水泥类供应商名录
    4  哈尔滨木材类供应商名录 等等。
    通过触发器有一个好处,这样写材料类别的pk字段容易写,因为每个pk字段都必须是唯一的,我增加11个类的时候可以依次加1,另外就是pk_father那个字段可以指定,就是:new的father。
    但是有一个缺陷就是必须每次要增加一个。下面说第二个写法.
    2,存储过程。
    存储过程的时候要用到地级市作为变量,这个我可以通过sql查询出来,因为地级市对应的pk_father那个字段为空,可是生下来怎么写,真的不知道了。
    我就写过触发器,存储过程没有用过。
    攻城师请帮助

    6.10号 22:50更新:

    写了一个晚上,最终还是认为触发器比较靠谱。

    注:触发器仅写了第一个类别的insert,其他的10个因为是类似,省略。

    create or replace trigger ADDAREA
      before insert on bd_areacl  
      for each row
    declare
      -- local variables here
       
    begin
      if length(:new.areaclcode)='8' and substr(:new.areaclcode,-2,2)='01'
        then
          insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'02',
             replace(:new.areaclname,'地材类供应商名录','')||'块材类供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '02'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
            end if;      
    end ADDAREA;

    效果图:

    这是增加了一个‘延安地材类供应商名录’之后的效果图(刷新后),试验证明这个触发器不影响bd_areacl的另外一个触发器,我项目的NC增加之后,分公司的地区分类也出现了。

     这是后台表的情况,可以看到ts完全是一样,pk_areacl做的不好,不过我不知道怎么做成和系统一样的那种按照字母递增(字母不够变成数字),只要开头丑些。

    6.11号 9.01更新,等待高手指正。

    触发器写出来了,效果还可以,缺点有几个:
    1,必须先手工录入地区城市下的第一个材料商类别,以此作为:new给下面11个材料商类别使用;
    2,剩余的11个材料商类别在触发器里面一个个录入insert,所有触发器特别的长;
    3,材料商对应后台表的一个字段pk_areacl没有系统自动产生的那样美观,系统是长度20位,前几位都是0001X1开始,然后自动产生,最末级是英文字母依次排列,不够的时候变成数字。
    请问,这11个类别可否作为变量或者数组先写好,然后02-11个类别也作为变量,这样可否把触发器优化写的简洁些?

     17:30更新:改进写法,增加名称的变量,这样即使第一个写错,下面的新增的11个也没有问题

    create or replace trigger ADDAREA
      before insert on bd_areacl  
      for each row
    declare
      -- local variables here
       
      vname char(10); 
    begin
     select areaclname  into vname from bd_areacl where pk_areacl=:new.pk_fatherarea;
      if length(:new.areaclcode)='8' and substr(:new.areaclcode,-2,2)='01'
        then
          insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'02',
             trim(replace(vname,'',''))||'块材类供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '02'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
             insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'03',
             trim(replace(vname,'',''))||'水泥类供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '03'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
          insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'04',
             trim(replace(vname,'',''))||'木材类供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '04'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
             insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'05',
             trim(replace(vname,'',''))||'金属类供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '05'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
             insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'06',
             trim(replace(vname,'',''))||'高分子材料类供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '06'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
             insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'07',
             trim(replace(vname,'',''))||'电工材料类供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '07'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
             insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'08',
             trim(replace(vname,'',''))||'安全防护用品器材类供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '08'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
             insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'09',
             trim(replace(vname,'',''))||'其他材料类供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '09'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             ); 
          insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'10',
             trim(replace(vname,'',''))||'器材租赁供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '10'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
             insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'11',
             trim(replace(vname,'',''))||'专业分包供应商名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '11'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
            insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||'12',
             trim(replace(vname,'',''))||'税款、投标类他项名录' ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             '12'||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
        end if;      
    end ADDAREA;

     

    必须要使用trim,不知道为什么不加的话后面总有空格。

     6.13号16:04更新:

    感谢南京一路交给的case用法,我终于可以实现两个变量之间的一一对应,这样极大的简化了trigger的长度

    ps:一个汉字两个字节,一个char是一个字节

    create or replace trigger ADDAREA12
    
      before insert on bd_areacl  
      for each row
    declare
      -- local variables here
      vsupply char(40);
      vname char(20); 
      i number;
    begin  
        
      for i in 2..12 loop
         case 
        when i=2 then vsupply:='块材类供应商名录';
        when i=3 then vsupply:='水泥类供应商名录';
        when i=4 then vsupply:='木材类供应商名录';
        when i=5 then vsupply:='金属类供应商名录';
        when i=6 then vsupply:='高分子材料类供应商名录';
        when i=7 then vsupply:='电工材料类供应商名录';
        when i=8 then vsupply:='安全防护用品器材供应商名录';
        when i=9 then vsupply:='其他材料类供应商名录';
        when i=10 then vsupply:='器材租赁供应商名录';
        when i=11 then vsupply:='专业分包供应商名录';     
        else vsupply:='税款、投标类他项名录'; 
         end case;
        
     select areaclname  into vname from bd_areacl where pk_areacl=:new.pk_fatherarea;
      if length(:new.areaclcode)='8' and substr(:new.areaclcode,-2,2)='01'
        then
          insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||lpad(i,2,'0'),
             trim(replace(vname,'',''))||vsupply ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             lpad(i,2,'0')||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
           
        end if;      
    end loop;
    end ADDAREA12;

    前后台都ok

    23:10分更新case的位置,这样容易理解

    create or replace trigger ADDAREA
    
      before insert on bd_areacl  
      for each row
    declare
      -- local variables here
      vsupply char(40);
      vname char(20); 
      i number;
    begin  
        
      for i in 2..12 loop
        
        
     select areaclname  into vname from bd_areacl where pk_areacl=:new.pk_fatherarea;
      if length(:new.areaclcode)='8' and substr(:new.areaclcode,-2,2)='01'
       
        then
            case 
    
        when i=2 then vsupply:='块材类供应商名录';
        when i=3 then vsupply:='水泥类供应商名录';
        when i=4 then vsupply:='木材类供应商名录';
        when i=5 then vsupply:='金属类供应商名录';
        when i=6 then vsupply:='高分子材料类供应商名录';
        when i=7 then vsupply:='电工材料类供应商名录';
        when i=8 then vsupply:='安全防护用品器材供应商名录';
        when i=9 then vsupply:='其他材料类供应商名录';
        when i=10 then vsupply:='器材租赁供应商名录';
        when i=11 then vsupply:='专业分包供应商名录';     
        else vsupply:='税款、投标类他项名录'; 
         end case;
          insert into bd_areacl 
          (
            areaclcode,
            areaclname,
            def1,
            def2,
            def3,
            def4,
            def5,
            dr,
            mnecode,
            pk_areacl,
            pk_corp,
            pk_fatherarea,
            ts
            )
          values
            (
             substr(:new.areaclcode,0,6)||lpad(i,2,'0'),
             trim(replace(vname,'',''))||vsupply ,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             lpad(i,2,'0')||substr(:new.pk_areacl,-18,18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts
             );
           
        end if;      
    end loop;
    end ADDAREA;

     2012.6.24 16:35更新case的用法2

     

       
      for i in 2..12 loop
         case i
        when 2 then vsupply:='块材类供应商名录';
        when 3 then vsupply:='水泥类供应商名录';
        when 4 then vsupply:='木材类供应商名录';
        when 5 then vsupply:='金属类供应商名录';
        when 6 then vsupply:='高分子材料类供应商名录';
        when 7 then vsupply:='电工材料类供应商名录';
        when 8 then vsupply:='安全防护用品器材供应商名录';
        when 9 then vsupply:='其他材料类供应商名录';
        when 10 then vsupply:='器材租赁供应商名录';
        when 11 then vsupply:='专业分包供应商名录';     
        else vsupply:='税款、投标类他项名录'; 
         end case;
        
     select areaclname  into vname from bd_areacl where pk_areacl=:new.pk_fatherarea;

    2012 6 29更新select into变量的写法

    create or replace trigger ADDAREA12
    
      before insert on bd_areacl  
      for each row
    declare
      -- local variables here
      vsupply bd_areacl.areaclname%type;
      vname   char(20);
      i       number;
    begin
    
      for i in 2 .. 12 loop
        --得到材料11个分类
        select replace(areaclname, '上海', '')
          into vsupply
          from bd_areacl
         where areaclname like '上海%'
           and length(areaclcode) = 8
           and substr(areaclcode, -2, 2) = lpad(i, 2, '0');
       
        --得到当前录入城市名 
        select areaclname
          into vname
          from bd_areacl
         where pk_areacl = :new.pk_fatherarea;
        if length(:new.areaclcode) = '8' and
           substr(:new.areaclcode, -2, 2) = '01' then
          insert into bd_areacl
            (areaclcode,
             areaclname,
             def1,
             def2,
             def3,
             def4,
             def5,
             dr,
             mnecode,
             pk_areacl,
             pk_corp,
             pk_fatherarea,
             ts)
          values
            (substr(:new.areaclcode, 0, 6) || lpad(i, 2, '0'),
             trim(replace(vname, '', '')) || vsupply,
             :new.def1,
             :new.def2,
             :new.def3,
             :new.def4,
             :new.def5,
             :new.dr,
             :new.mnecode,
             lpad(i, 2, '0') || substr(:new.pk_areacl, -18, 18),
             :new.pk_corp,
             :new.pk_fatherarea,
             :new.ts);
        
        end if;
      end loop;
    end ADDAREA12;

     

  • 相关阅读:
    ubuntu 上安装ssh
    应用架构设计原则、模式摘录
    经典算法摘录
    CSS3选择器笔记
    微信支付 统一下单 字段 body 为中文时 报【签名错误】解决方案(C# SDK)
    C#获取gif帧数
    C#根据byte前两位获取图片扩展名
    使用Amazon AWS SNS 发送 SMS 消息 .net
    MyCAT全局序列号-数据库方式
    MyCAT入门实践
  • 原文地址:https://www.cnblogs.com/sumsen/p/2544363.html
Copyright © 2011-2022 走看看