SUMSEN

Oracle&Sql爱好者,用友NC管理员

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

目前使用数个月的触发器

create or replace trigger ADDC4
  before insert on bd_cubasdoc
  for each row
declare
  -- local variables here
  v_exp varchar2(200);
  
begin
  
     --空格的客商
    if  regexp_like(:new.custname,'[[:space:]]')
     then raise_application_error(-20001, '客商名称:' || :new.custname || '有空格,请修改');
        end if;
        
     --重复名称、营业执照、纳税人登记号客商
    select case
             when custname = :new.custname then
              '客商名称:' || :new.custname || '已存在,请在已有客商修改增行!'
             when engname = :new.engname and length(:new.engname) > 3 then
              '客商营业执照:' || :new.engname || '已存在,请在已有客商修改增行!'
             when taxpayerid = :new.taxpayerid and length(:new.taxpayerid) > 3 then
              '客商纳税人登记号:' || :new.taxpayerid || '已存在,请在已有客商修改增行!'
               ELSE
              '其他错误'
           END
      INTO v_exp
      from bd_cubasdoc
     where custname = :new.custname
        or (engname = :new.engname and length(:new.engname) > 3) --营业执照或身份照
        or (taxpayerid = :new.taxpayerid and length(:new.taxpayerid) > 3);--纳税人登记号
   if v_exp is not null then   
    raise_application_error(-20001, v_exp);
     end if;--相当于前面 else return?
   
     --正常客商通过exception,否则触发器提示“未找到任何数据”
   exception
  when no_data_found then  
    return;
   
end;

发现了问题:

如果同时有超过两个的错误信息,比如营业执照和纳税人登记证号同时错误,就会有以下的报错

原因已经找到:

下面的营业执照:640205700022680和纳税人登记号:500903L28943062都已经在客商表中,并且属于不同的客商

在上面的select into where条件是

where custname = :new.custname
        or (engname = :new.engname and length(:new.engname) > 3) --营业执照或身份照
        or (taxpayerid = :new.taxpayerid and length(:new.taxpayerid) > 3);--纳税人登记号

or的关系导致查询到了两个值into到变量v_exp,但是
select into的写法不允许有多个值,每次只能一个值

另外,上面case when条件和下面的where条件虽然是一样,但是也不是多余,因为case when每次只出现一个值,是通过when的条件来raise错误信息

2014-01-17 09:45:42 何涛联通机房一夜的研究咨询成果

本来想写

if  then
else if
else if
else if
end if
end

问了何涛,原来这个是C(java)的写法,oracle的是这样

select xx into from where

if then

elsif  then

elsif  then

else

<return>

end if;

下面的写法编译通过,nvl的用法更好,但是

select  nvl(engname,1) into v_exp2 from bd_cubasdoc where engname = :new.engname and length(:new.engname) > 3;
      raise_application_error(-20001,v_exp2); 
    select nvl(taxpayerid,1) into v_exp3 from bd_cubasdoc where taxpayerid = :new.taxpayerid and length(:new.taxpayerid) > 3;
       raise_application_error(-20001,v_exp3); 

select into每次必须要有值,否则就会报找不到数据:如果营业执照有,纳税人号没有,就会报找不到数据

create or replace trigger acc
  before insert on bd_cubasdoc
  for each row
declare
  -- local variables here
  v_exp1 varchar2(200);
   v_exp2 varchar2(200);
    v_exp3 varchar2(200);  
begin  
     --空格的客商
    if  regexp_like(:new.custname,'[[:space:]]')
     then raise_application_error(-20001, '客商名称:' || :new.custname || '有空格,请修改');
        end if;        
     --重复名称
   /*  select custname into v_exp1 from bd_cubasdoc where custname = :new.custname ;
     if v_exp1 is not null then
        raise_application_error(-20001, '客商名称:' || :new.custname || '已存在,请在已有客商修改增行!');
        end if;*/
   --重复营业执照        
    select  nvl(engname,1) into v_exp2 from bd_cubasdoc where engname = :new.engname and length(:new.engname) > 3;
      raise_application_error(-20001,v_exp2); 
    select nvl(taxpayerid,1) into v_exp3 from bd_cubasdoc where taxpayerid = :new.taxpayerid and length(:new.taxpayerid) > 3;
       raise_application_error(-20001,v_exp3); 
     
     if v_exp2 <>'1' and v_exp3  <>'1' then
            raise_application_error(-20001, '客商营业执照和纳税人号都已存在!');            
      elsif    
      v_exp2  <>'1' and v_exp3='1' then
        raise_application_error(-20001, '客商营业执照:' || :new.engname || '已存在,请在已有客商修改增行!');         
    --重复纳税人登记号 
    elsif  v_exp3 <>'1' and  v_exp2='1'  then
        raise_application_error(-20001, '客商纳税人登记号:' || :new.taxpayerid || '已存在,请在已有客商修改增行!');         
    else
      return;
      end if;
   end;     

 

2014-01-17 01:43:44

java.lang.RuntimeException: ORA-01403: 未找到数据
ORA-06512: 在 "XMV502.ADDC4", line 13

找不到(正常的客商=可以插入的客商)的异常处理,见上

 exception
  when no_data_found then  
    return;
这个写法和else return一样的效果,见下
CREATE OR REPLACE TRIGGER FTS_V_B
before insert or update on fts_voucher_b
for each row
declare
-- local variables here
accode char(6);
vcode char(6);
vRowsCount number;
begin
select nvl(count(*),0) into vRowsCount from fts_voucher_b, gl_freevalue, bd_accid
where gl_freevalue.freevalueid=:new.pk_ass
and bd_accid.pk_accid=:new.pk_account
and length(gl_freevalue.valuecode) = '6'
and substr(gl_freevalue.valuecode, 0, 1) = '0';

if vRowsCount > 0 then
select distinct bd_accid.accidcode, gl_freevalue.valuecode into accode,vcode
from fts_voucher_b, gl_freevalue, bd_accid
where gl_freevalue.freevalueid=:new.pk_ass
and bd_accid.pk_accid=:new.pk_account
and length(gl_freevalue.valuecode) = '6'
and substr(gl_freevalue.valuecode, 0, 1) = '0';
/* else
return;*/

end if;

if accode<>vcode then
raise_application_error(-20001,'次结算凭证账户'||accode||'和客商'||vcode|| '不一致,请修改!');

end if;
exception

when no_data_found then
return;
end FTS_V_B;

 

into 必须找导致 

 

posted on 2014-01-08 16:28  sumsen  阅读(354)  评论(0编辑  收藏  举报