谢谢你的参与。我用的就是触发器啊,可是在Insert触发器里好象不能对新增的记录进行修改吧?比如:我是给t1建立的触发器,我想在新增时根据条件将t1.iflag列改的值由0改成3,:new.iflag=3,不能执行啊!

解决方案 »

  1.   

    我还是贴出代码来吧:
    create or replace trigger AoPlanCarSet
      instead of insert on rgorder  
      for each row
    declare
      -- local variables here
      rec_Limit Biparameter%rowtype;
      isManu number(2,0);
      cursor LimitCur is 
        select * from Biparameter;    
    begin
      if :new.cTransNo<>'001' then
         return;
      end if;   
      select bAuto into isManu from biset;
      if isManu=0 then
        begin
          update rgOrder set iFlag=2 where vcOrderNo=:new.vcOrderNo;
          return;
        end;   
      end if;
      open LimitCur;
      loop
        fetch LimitCur into rec_Limit;
        exit when LimitCur%NOTFOUND;
        if rec_Limit.Itype=1 then
          begin
            if trim(rec_Limit.Vccontent)=trim(:new.vcOrderNo) then
              begin
                update rgOrder set iFlag=3 where vcOrderNo=:new.vcOrderNo;          
                return;
              end;  
            end if;   
          end;
       elsif rec_Limit.Itype=2 then
         begin
            if rec_Limit.Bflag = 1 then
              begin
                if to_char(:new.dtOrderDate,'yyyy-mm-dd')>=to_char(rec_Limit.Dtbegindate,'yyyy-mm-dd') 
                    and to_char(:new.dtOrderDate,'yyyy-mm-dd')<=to_char(rec_Limit.Dtenddate,'yyyy-mm-dd') then
                  begin
                    update rgOrder set iFlag=3 where vcOrderNo=:new.vcOrderNo;              
                    Ao_Package.changevalue := 3;                            
                    return;
                  end;  
                end if;           
              end;
            end if;       
         end;  
         elsif rec_Limit.Itype=3 then
           begin
             if trim(rec_Limit.Vccontent)=trim(:new.vcStyleNo) then
               begin
                 update rgOrder set iFlag=3 where vcOrderNo=:new.vcOrderNo;              
                 return;        
               end;
             end if;  
           end;      
       end if;
      end loop;
      update rgOrder set iFlag=5 where vcOrderNo=:new.vcOrderNo;
      commit;
    end AoPlanCarSet;
      

  2.   

    大概的形式如下:
    create or replace trigger AoPlanCarSet
      before insert on rgorder  
      for each row
    begin
      ...
      if vcContent='aa' then
         :new.vcOrderNo=3;
      end if;
      ...
    end;
      

  3.   

    问题出在“for each row”,行级触发器是不能对自己进行操作的,语句级的就可以了
      

  4.   

    呵呵,问题解决,问题出在我用了update语句,其实只要用:new.iflag就可以修改值了。谢谢大家!不过现在又有新问题了,就是我又在这个表上做了一个修改触发器,我需要当iflag从2变成1的时候做一些事情,做完后再将标志改为3。但是在update触发器里好象不支持更新:new里面的数据啊!哪位告诉我应该怎么做啊?
      

  5.   

    晕,我总喜欢在after update里编写触发器,其实应该在Before update里面做事。
      

  6.   

    create or replace trigger AoAuPlanCarChange
      before update on rgorder  
      for each row
    declare
      -- local variables here
      rec_Limit Biparameter%rowtype;
      cursor LimitCur is 
        select * from Biparameter;      
    begin
      if (:old.iFlag=2) and (:new.iFlag=1) then
         begin
           --由2转变成1,这种情况出现在人工订单转自动订单时,也要进行过滤后再进行排车(人工或是自动排)
           open LimitCur;
           loop
             fetch LimitCur into rec_Limit;
             exit when LimitCur%NOTFOUND;
             if rec_Limit.Itype=1 then
               begin
               --过滤出订单号
                 if trim(rec_Limit.Vccontent)=trim(:new.vcOrderNo) then
                    begin
                      :new.iFlag := 3;          
                      return;
                    end;  
                 end if;   
               end;
             elsif rec_Limit.Itype=2 then
               begin
               --过滤出货物发往地
                 if rec_Limit.Bflag = 1 then
                    begin
                       if to_char(:new.dtOrderDate,'yyyy-mm-dd')>=to_char(rec_Limit.Dtbegindate,'yyyy-mm-dd') 
                           and to_char(:new.dtOrderDate,'yyyy-mm-dd')<=to_char(rec_Limit.Dtenddate,'yyyy-mm-dd') then
                        begin
                          :new.iFlag := 3;          
                          return;
                        end;  
                      end if;           
                    end;
                 end if;       
               end;  
             elsif rec_Limit.Itype=3 then
               begin
               --过滤出车型
                 if trim(rec_Limit.Vccontent)=trim(:new.vcStyleNo) then
                    begin
                      :new.iFlag := 3;          
                      return;        
                    end;
                 end if;  
               end;      
             end if;                   
           end loop;
           :new.iFlag := 5; 
           AoPlanCar(:new.vcOrderNo);              
         end;
      end if;   
    end AoAuPlanCar;
      

  7.   

    你贴出AoPlanCar(:new.vcOrderNo); 的代码看看
      

  8.   

    create or replace procedure AoPlanCar(orderID varchar2) is
      CarNum      numeric(2, 0); 
      Driver_No   varchar2(30);  
      IsBalance   numeric(2, 0); 
      BalanceMile numeric(9, 2); 
      DriverMile  numeric(9, 2); 
      FleetNo     varchar2(30); 
      cursor Driver_Cur is
        select vcDriverNo from TMDriverQueue where bCome = 1 order by dtDate;
    begin
      select dcQty into CarNum from rgOrder where vcOrderNo = orderID;
      if (CarNum is null) or (CarNum=0) then
         return;
      end if;  
      while CarNum > 0 loop
        open Driver_Cur;
        loop
          fetch Driver_Cur
            into Driver_No;
          exit when Driver_Cur%notfound;
          select bBalance, dcBalance into IsBalance, BalanceMile from BISet;
          if IsBalance = 1 then
            begin
              select dcBalance, cFleetNo  into DriverMile, FleetNo from BIDriver
               where vcDriverNo = Driver_No;
              if BalanceMile > DriverMile then
                begin
                  insert into rgOrderDetail
                    (Vcorderno, Cfleetno, Vcdriverno)
                  values
                    (orderID, FleetNo, Driver_No);
                  delete from TMDriverQueue where vcDriverNo = Driver_No; 
                  update BIDriver
                     set vcOrderList = orderID
                   where vcDriverNo = Driver_No;
                   exit;
                end;
              end if;
            end;
          else
            begin
              insert into rgOrderDetail
                (Vcorderno, Cfleetno, Vcdriverno)
              values
                (orderID, FleetNo, Driver_No);
              delete from TMDriverQueue where vcDriverNo = Driver_No;           update BIDriver set vcOrderList = orderID
               where vcDriverNo = Driver_No;
               exit;
            end;
          end if;
        end loop;
        close Driver_Cur;
        CarNum := CarNum - 1;
      end loop;
      --此订单排完,写订单信息   
      update rgOrder
         set bAssign = 1, dtAssign = sysdate, iAssignType = 1,iFlag=6
       where vcOrderNo = orderID;
      commit;
       exception
          when others then   
            rollback;            
    end AoPlanCar;
      

  9.   

    你在rgOrder表的before insert触发器中调用 AoPlanCar(:new.vcOrderNo) 是不对,因为那里记录并没有真正插入数据库中去,将AoPlanCar(:new.vcOrderNo)的调用放到rgOrder表的另一个after insert触发器中去。
      

  10.   

    armu80830(此情可待) 说的不错,我的update触发器修改成功,但before insert触发器正发生了如你所说的错误。我的rgOrder表和rgOrderDetail表建立了主外键关联,在Before Insert时主表并没有加入记录到rgOrder表中,Oracle报告了主记录不存在!这种问题应该怎么解决呢?
      

  11.   

    新问题的代码:
    create or replace trigger AoPlanCarSet
      before insert on rgorder  
      for each row
    declare
      -- local variables here
      CarNum      numeric(2, 0); 
      Driver_No   varchar2(30); 
      IsBalance   numeric(2, 0); 
      BalanceMile numeric(9, 2); 
      DriverMile  numeric(9, 2); 
      FleetNo     varchar2(30); --司机车队编号
      cursor Driver_Cur is
        select vcDriverNo from TMDriverQueue where bCome = 1 order by dtDate;  
      rec_Limit Biparameter%rowtype;
      isManu number(2,0);
      cursor LimitCur is 
        select * from Biparameter;    
    begin
      if :new.cTransNo<>'001' then
         return;
      end if;   
      select bAuto into isManu from biset;
      if isManu=0 then
        begin
          :new.iFlag := 2;
    --      update rgOrder set iFlag=2 where vcOrderNo = :new.vcOrderNo;
          return;
        end;   
      end if;
      open LimitCur;
      loop
        fetch LimitCur into rec_Limit;
        exit when LimitCur%NOTFOUND;
        if rec_Limit.Itype=1 then
          begin
          --过滤出订单号
            if trim(rec_Limit.Vccontent)=trim(:new.vcOrderNo) then
              begin
               :new.iFlag := 3;          
                return;
              end;  
            end if;   
          end;
       elsif rec_Limit.Itype=2 then
         begin
            if rec_Limit.Bflag = 1 then
              begin
                if to_char(:new.dtOrderDate,'yyyy-mm-dd')>=to_char(rec_Limit.Dtbegindate,'yyyy-mm-dd') 
                    and to_char(:new.dtOrderDate,'yyyy-mm-dd')<=to_char(rec_Limit.Dtenddate,'yyyy-mm-dd') then
                  begin
                    :new.iFlag := 3;          
                    return;
                  end;  
                end if;           
              end;
            end if;       
         end;  
         elsif rec_Limit.Itype=3 then
           begin
             if trim(rec_Limit.Vccontent)=trim(:new.vcStyleNo) then
               begin
                 :new.iFlag := 3;          
                 return;        
               end;
             end if;  
           end;      
       end if;
      end loop;
      :new.iFlag := 5; 
      select :new.dcQty into CarNum from dual;
      if (CarNum is null) or (CarNum=0) then
         return;
      elsif CarNum<:new.dcQty then
        begin
        --如果司机数量不够,则将订单转入人工处理          
          :new.iFlag := 3;
          return;
        end;     
      end if;  
      while CarNum > 0 loop
        --读取司机排队信息
        open Driver_Cur;
        loop
          fetch Driver_Cur
            into Driver_No;
          exit when Driver_Cur%notfound;
          select bBalance, dcBalance into IsBalance, BalanceMile from BISet;
          if IsBalance = 1 then
            begin
              select dcBalance, cFleetNo  into DriverMile, FleetNo from BIDriver
               where vcDriverNo = Driver_No;
              if BalanceMile > DriverMile then
                begin
                  insert into rgOrderDetail
                    (Vcorderno, Cfleetno, Vcdriverno)
                  values
                    (:new.vcOrderNo, FleetNo, Driver_No);
                  delete from TMDriverQueue where vcDriverNo = Driver_No; --将司机排队信息删除
                  --写司机当前订单号
                  update BIDriver
                     set vcOrderList = :New.vcOrderNo
                   where vcDriverNo = Driver_No;
                   exit;
                end;
              end if;
            end;
          else
            --不平衡公里
            begin
              --继续排车,新增一条           
              insert into rgOrderDetail
                (Vcorderno, Cfleetno, Vcdriverno)
              values
                (:new.vcOrderNo, FleetNo, Driver_No);
              delete from TMDriverQueue where vcDriverNo = Driver_No; --将司机排队信息删除
              --写司机当前订单号
              update BIDriver set vcOrderList = :new.vcOrderNo
               where vcDriverNo = Driver_No;
               exit;
            end;
          end if;
        end loop;
        close Driver_Cur;
        CarNum := CarNum - 1;
      end loop;
      --此订单排完,写订单信息   
      :new.bAssign := 1;:new.dtAssign := sysdate; :new.iAssignType := 1;:new.iFlag :=6;  
    end AoPlanCarSet;