zoukankan      html  css  js  c++  java
  • 待解决:新增客商校验触发器|两个错误|

    目前使用数个月的触发器

    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 必须找导致 

  • 相关阅读:
    Oracle最大连续访问天数
    oracle中MINUS
    sql中含有中文,export oralce编码格式的环境变量
    alternate_file_dcol_rollback
    oracle查询分区表
    hive创建表sql
    使用ANSI改变终端输出样式
    Golang中的空字符,似花不是花
    程序员必看 Linux 常用命令(重要)
    MongoDB入门介绍与案例分析
  • 原文地址:https://www.cnblogs.com/sumsen/p/3510905.html
Copyright © 2011-2022 走看看