开户银行付款账号不给修改trigger|3种写法||更新itpub版主的i循环|

最初的思路是在or后面直接增加付过款的pk,如下

create or replace trigger CSpcace_ACCBANK
before insert or update on bd_accbank  
  for each row
declare
  -- local variables here
begin

if regexp_like(:new.bankacc,'[[:space:]]') or
    regexp_like(:new.combineaccnum,'[[:space:]]') or
    regexp_like(:new.unitname,'[[:space:]]') or
   :new.pk_accbank  in
     ( select ncv5.bd_accbank.pk_accbank from ncv5.bd_cubasdoc,ncv5.arap_djfb,ncv5.bd_cumandoc

        where ncv5.arap_djfb.ksbm_cl = ncv5.bd_cumandoc.pk_cumandoc
         and ncv5.bd_cumandoc.pk_cubasdoc = ncv5.bd_cubasdoc.pk_cubasdoc
         and ncv5.bd_accbank.pk_accbank = ncv5.arap_djfb.skyhzh
         and ncv5.arap_djfb.payflag in ('1', '2')
    )
     then
    raise_application_error(-20001,'银行账号'||:new.bankacc||'或联行号'||:new.combineaccnum||'或单位名称'||:new.unitname||'有空格,请修改!');
end if;  
  
end CSpcace_ACCBANK; 

可是编译不通过,

到现在也不知道oracle为什么不支持or后面使用子查询。

经过研究,得到三种写法,其中第二种是itpub版主写的,不够个人感觉我写的第三个方法最简洁(*^__^*) 嘻嘻……。

2012.7.5 17:27更新:悲剧啊,我认为最好的第三个方法,反而不能使用,具体看第三种写法

方法一,使用游标,注意写法,不在游标定义里面的select使用子查询,并且和select into的区别是这里不用:new(测试真正没有问题)

create or replace trigger CSpcace_ACCBANK
before insert or update on bd_accbank  
  for each row
declare
  -- local variables here
  pk_bas bd_accbank.pk_accbank%type;
 cursor basjob(id varchar2) is 
 select pk_accbank from ncv5.bd_cubasdoc,ncv5.arap_djfb,ncv5.bd_cumandoc,ncv5.bd_accbank

        where ncv5.arap_djfb.ksbm_cl = ncv5.bd_cumandoc.pk_cumandoc
         and ncv5.bd_cumandoc.pk_cubasdoc = ncv5.bd_cubasdoc.pk_cubasdoc
         and ncv5.bd_accbank.pk_accbank = ncv5.arap_djfb.skyhzh
         and ncv5.arap_djfb.payflag in ('1', '2')
 and pk_accbank=id;
 
 
 
begin
 open basjob(:new.pk_accbank);
 loop
   fetch basjob into pk_bas;
   exit when basjob%notfound;
   end loop;
   close basjob;
   
 if regexp_like(:new.bankacc,'[[:space:]]') or
    regexp_like(:new.combineaccnum,'[[:space:]]') or
    regexp_like(:new.unitname,'[[:space:]]') or
   pk_bas is not null
     then
    raise_application_error(-20001,'注意:银行账号'||:new.bankacc||'或联行号'||:new.combineaccnum||'或单位名称'||:new.unitname||'有空格或已付款成功,不能修改!');
 end if;  
  
end CSpcace_ACCBANK;

方法二,itpub版主的i loop循环写法http://www.itpub.net/thread-1632059-1-1.html

create or replace trigger CSpcace_ACCBANK2
before insert or update on bd_accbank  
  for each row
declare

  -- local variables here
 begin 
   if regexp_like(:new.bankacc,'[[:space:]]') or
    regexp_like(:new.combineaccnum,'[[:space:]]') or
    regexp_like(:new.unitname,'[[:space:]]') then
    raise_application_error(-20001,'注意:银行账号'||:new.bankacc||'或联行号'||:new.combineaccnum||'或单位名称'||:new.unitname||'有空格或已付款成功,不能修改!');
end if;  

for i in (select * from (select ncv5.bd_accbank.pk_accbank from ncv5.bd_cubasdoc,ncv5.arap_djfb,ncv5.bd_cumandoc,ncv5.bd_accbank
        where ncv5.arap_djfb.ksbm_cl = ncv5.bd_cumandoc.pk_cumandoc
         and ncv5.bd_cumandoc.pk_cubasdoc = ncv5.bd_cubasdoc.pk_cubasdoc
         and ncv5.bd_accbank.pk_accbank = ncv5.arap_djfb.skyhzh
         and ncv5.arap_djfb.payflag in ('1', '2'))
where pk_accbank= :new.pk_accbank 
 and rownum = 1)
  loop
   raise_application_error(-20001,'注意:银行账号'||:new.bankacc||'或联行号'||:new.combineaccnum||'或单位名称'||:new.unitname||'有空格或已付款成功,不能修改!');
   exit;
end loop;

  
end  ;

方法三,使用select into写法,这里有需要注意:(有bug)

1,使用:new,

2,from后面不使用creat trigger on的表bd_accbank,

3,select的不能是pk_accbank而是客商pk,否则会有提示发生

create or replace trigger CSpcace_ACCBANK2
before insert or update on bd_accbank  
  for each row
declare
pk_bas varchar2(20);
  -- local variables here
 begin 
   select distinct ncv5.bd_cumandoc.pk_cubasdoc into pk_bas from ncv5.bd_cubasdoc,ncv5.arap_djfb,ncv5.bd_cumandoc

        where ncv5.arap_djfb.ksbm_cl = ncv5.bd_cumandoc.pk_cumandoc
         and ncv5.bd_cumandoc.pk_cubasdoc = ncv5.bd_cubasdoc.pk_cubasdoc
         and ncv5.arap_djfb.skyhzh=:new.pk_accbank 
         and ncv5.arap_djfb.payflag in ('1', '2');
 if regexp_like(:new.bankacc,'[[:space:]]') or
    regexp_like(:new.combineaccnum,'[[:space:]]') or
    regexp_like(:new.unitname,'[[:space:]]') or
    pk_bas is not null 
    
     then
    raise_application_error(-20001,'注意:银行账号'||:new.bankacc||'或联行号'||:new.combineaccnum||'或单位名称'||:new.unitname||'有空格或已付款成功,不能修改!');
 end if;  
  
end  ;
通过客商增行录入新的账号的时候,因为:new不存在,因此会报错:

23:21更新:

区分两个不同的trigger,一个是检测空格的,一个是检测付款成功修改账号和单位名称的:

1,空格:

create or replace trigger CSpcace_ACCBANK
before insert or update on bd_accbank  
  for each row
declare
  -- local variables here
  
begin 
 if regexp_like(:new.bankacc,'[[:space:]]') or
    regexp_like(:new.combineaccnum,'[[:space:]]') or
    regexp_like(:new.unitname,'[[:space:]]') 
     then
    raise_application_error(-20001,'注意:银行账号、联行号、单位名称中有空格!');
 end if;    
end ;

2,单位名称(使用游标)

create or replace trigger  CHECK_ACCBANK
  before UPDATE on   BD_ACCBANK
  for each row
declare
  -- local variables here
  pk_bas bd_accbank.pk_accbank%type;
     
 cursor basjob(id varchar2) is 
 select pk_accbank from ncv5.bd_cubasdoc,ncv5.arap_djfb,ncv5.bd_cumandoc,ncv5.bd_accbank
        where ncv5.arap_djfb.ksbm_cl = ncv5.bd_cumandoc.pk_cumandoc
         and ncv5.bd_cumandoc.pk_cubasdoc = ncv5.bd_cubasdoc.pk_cubasdoc
         and ncv5.bd_accbank.pk_accbank = ncv5.arap_djfb.skyhzh
         and ncv5.arap_djfb.payflag in ('1', '2')
         and pk_accbank=id; 
 
begin
 open basjob(:new.pk_accbank);
 loop
   fetch basjob into pk_bas;
   exit when basjob%notfound;
   end loop;
   close basjob;
 if pk_bas is not null then
   if :new.bankacc<>:old.bankacc or
     :new.unitname<>:old.unitname
     then
   raise_application_error(-20001,'注意:客商账户已成功付款,不能修改账号和名称!');
   end if;
   end if;
  end;  

 2012.7.10更新:new和:old差异率:

create or replace trigger C_ACCBANK_NET
  before UPDATE on   BD_ACCBANK
  for each row
declare
  -- local variables here
  pk_bas bd_accbank.pk_accbank%type;
     
 cursor basjob(id varchar2) is 
 select pk_accbank from ncv5.bd_cubasdoc,ncv5.arap_djfb,ncv5.bd_cumandoc,ncv5.bd_accbank
        where ncv5.arap_djfb.ksbm_cl = ncv5.bd_cumandoc.pk_cumandoc
         and ncv5.bd_cumandoc.pk_cubasdoc = ncv5.bd_cubasdoc.pk_cubasdoc
         and ncv5.bd_accbank.pk_accbank = ncv5.arap_djfb.skyhzh
         and ncv5.arap_djfb.payflag in ('1', '2')
         and pk_accbank=id; 
 
begin
 open basjob(:new.pk_accbank);
 loop
   fetch basjob into pk_bas;
   exit when basjob%notfound;
   end loop;
   close basjob;
 if pk_bas is not null then
  /* if :new.bankacc<>:old.bankacc or
     :new.unitname<>:old.unitname*/
    if utl_match.edit_distance_similarity(:old.bankacc,:new.bankacc)<'90' or
       utl_match.edit_distance_similarity(:old.unitname,:new.unitname)<'90'
     then
   raise_application_error(-20001,'注意:账户已成功付款,不能修改账号或单位名称!');
   end if;
   end if;
end;

 

原文地址:https://www.cnblogs.com/sumsen/p/2577790.html