请问高手,我现在有个自关联表,如何写这样的一个触发器?在本例中,
表 agentinfo 中的 usercode 和 agentcode 是一对表示上下级关系的字段
credit 字段则是对usercode的一个数值,当更新此credit字段时,
需要读取本表中的 usercode = 当前要更新的记录中的 agentcode 字段的 creditleft 字段进行比较
另外还有个问题请教我不抛出错误,只是让 update的行数为0,该怎样在触发器中实现?
目的是不希望调用程序进入错误处理感觉就跟没有符合条件的行被更新一样CREATE OR REPLACE TRIGGER T_BEFORE_UPDATE_AGENTINFO
  before update OF CREDIT on AGENTINFO  
  for each row
declare
v_creditleft agentinfo.creditleft%type;
v_credit agentinfo.credit%type;
CREDITLEFT_LIMIT EXCEPTION;
PRAGMA EXCEPTION_INIT(CREDITLEFT_LIMIT, -20002); 
PRAGMA AUTONOMOUS_TRANSACTION;
  -- local variables here
begin
  v_credit:=:old.credit-:new.credit;
  SELECT CREDITLEFT  into v_creditleft from agentinfo where usercode=:old.agentcode; ---错误发生在这句 
  if v_creditleft+v_credit<0 or :old.creditleft-v_credit<0 then
     RAISE CREDITLEFT_LIMIT;
  end if
 IF v_credit !=0 THEN
  UPDATE AGENTINFO SET CREDITLEFT=CREDITLEFT+v_credit WHERE usercode=:old.agentcode;
 UPDATE AGENTINFO SET CREDITLEFT=CREDITLEFT-v_credit WHERE usercode=:old.USERCODE;
  END IF;
end T_BEFORE_UPDATE_AGENTINFO;

解决方案 »

  1.   

    例如:表中有这样两条记录 
    记录1:usercode='00089',agentcode='any',credit=10000,creditleft=5000
    记录2:usercode='01234',agentcode='00089',credit=5000,creditleft=1000
    当执行下列sql命令时
    update agentinfo set credit=newvalue where usercode='01234'
    这时就需要 在上述触发器中实现
    取出 记录2中 agentcode 所指的也就是:记录1  usercode='00089'这一条记录
    作为判定条件现在错误发生在 读取记录1的时候
      

  2.   

    可能出现
    no_data_found
    too_many_rows
    这两种异常.
      

  3.   

    表中数据:
          usercode  agentcode     credit     creditleft
    ....
    16      00018      00015    50000.00      47000.00
    17      00019      00018     1000.00       1000.00
    ....
    执行 update agentinfo t set credit=2000 where usercode='00019'
    出现错误如下:
    ORA-00060 deadlock detected while waiting for resource
    ORA-06512 at "t_before_update_agentinfo", line 17
    ora-04088 error during execution of trigger 't_before_update_agentinfo'CREATE OR REPLACE TRIGGER T_BEFORE_UPDATE_AGENTINFO
      before update OF CREDIT on AGENTINFO
      for each row
    declare
    v_creditleft agentinfo.creditleft%type;
    v_credit agentinfo.credit%type;
    CREDITLEFT_LIMIT EXCEPTION;
    PRAGMA EXCEPTION_INIT(CREDITLEFT_LIMIT, -20002);
    PRAGMA AUTONOMOUS_TRANSACTION;
      -- local variables here
    begin
      v_credit:=:old.credit-:new.credit; 
      SELECT CREDITLEFT  into v_creditleft from agentinfo where usercode=:old.agentcode; 
      if v_creditleft+v_credit <0 or :old.creditleft-v_credit <0 then 
         RAISE CREDITLEFT_LIMIT; 
      end if;
      IF v_credit !=0 THEN 
        UPDATE AGENTINFO SET CREDITLEFT=CREDITLEFT+v_credit WHERE usercode=:old.agentcode; 
        UPDATE AGENTINFO SET CREDITLEFT=CREDITLEFT-v_credit WHERE usercode=:old.USERCODE; 
      END IF; 
    end;
      

  4.   

    报错检测到死锁,出错应该是在:
     IF v_credit !=0 THEN 
        UPDATE AGENTINFO SET CREDITLEFT=CREDITLEFT+v_credit WHERE usercode=:old.agentcode; 
        UPDATE AGENTINFO SET CREDITLEFT=CREDITLEFT-v_credit WHERE usercode=:old.USERCODE; 
      END IF;
    ========================================================================================触发器去更新的行,是引起触发的语句正在更新的行。这样会出错的。