SQL触发器代码:CREATE  trigger tri_insert on dbo.phonedata 
for update 
as 
declare @c int
begin
 select @c=count(i.ani) from phonedata p,inserted i 
  where p.subbecalleds=i.subbecalleds  and i.endtime <>' ' and i.userid is not null and i.state='y'
if @c > 0 
  begin 
insert into callend 
   select i.* from phonedata p , inserted i 
   where p.ani=i.ani and p.starttime=i.starttime and i.endtime <>' '  and i.userid is not null and i.state='y'
      delete  phonedata
       from phonedata a,
                               ( select i.ani,i.starttime from phonedata p , inserted i 
  where p.ani=i.ani and p.starttime=i.starttime and i.endtime <>' '  and i.userid is not null and i.state='y'
) callend
               where a.ani=callend.ani and a.starttime=callend.starttime
 end 
end

解决方案 »

  1. create or replace  trigger tri_insert 
    before update on phonedata 
    for each row
    as 
     c integer;
    begin
      select nvl(count(:new.ani),0) into c
      from phonedata p
      where p.subbecalleds=:new.subbecalleds  and :new.endtime <>' ' 
          and :new.userid is not null and :new.state='y';
      if c > 0  then
        insert into callend 
        select :new.* from phonedata p 
        where p.ani=:new.ani and p.starttime=:new.starttime and :new.endtime <>' ' 
             and :new.userid is not null and :new.state='y';
        delete from  phonedata a
        where a.ani=:new.ani and a.starttime=:new.starttime and :new.endtime <>' ' 
           and :new.userid is not null and :new.state='y' 
           and a.starttime=:new.starttime;
      end if;
    end tri_insert ;
    /
      

  2. Create or Replace trigger tri_insert
    after update on phonedata
    for each row
    declare
      v_count number;
    begin
      v_count=0;
      select count(:new.ani) into v_count from phonedata p 
      where p.subbecalleds=:new.subbecalleds  and :new.endtime <>' ' and :new.userid is not null and :new.state='y';
      if v_count > 0  then
       insert into callend 
       select :new.* from phonedata p
       where p.ani=:new.ani and p.starttime=:new.starttime and :new.endtime <>' '  and :new.userid is not null and :new.state='y';   delete from phonedata
       where p.ani=:new.ani and p.starttime=:new.starttime and :new.endtime <>' '  and :new.userid is not null and :new.state='y';
     end if;
    exception
     when NO_DATA_FOUND then raise_application_error(-20001,'failed operation!');
    end tri_insert;
      

  3. 嗯,ab5669(王长林),那个AS是多的,而且定义变量要加:declare。现在测试报错是:ORA-00936:缺少表达式,提示这句select :new.* from phonedata p 有错,赋值错误。
      

  4. mislrb(aben) ( ) ,怎么都在这句:select :new.* from phonedata p 提示:错误的赋值变量'NEW.'呢
      

  5. 我这没有Oracle的测试环境
    将:new分解为:new.ani,:new.starttime,:new.endtime,...试试
      

  6. 能说说你那个触发器的逻辑吗?相关表的结构,主键是怎样的?关键是
    select @c=count(i.ani) from phonedata p,inserted i 
      where p.subbecalleds=i.subbecalleds  and i.endtime <>' ' and i.userid is not null and i.state='y'
    的意义是什么?
      

  7. 主键是ani和starttime,phonedata表和callend表的结构一模一样,这个触发器的作用就是:phonedata表里的记录满足条件: endtime <>' '  and userid is not null and state='y'就把这条记录转到callend表里谢谢各位的帮助
      

  8. 需要增加一张临时表(事务结束就删除数据),结构就同phonedata完全一样(模仿sql server的inserted表),然后在after update for each row触发器中将新更改的记录写入临时表,在表级的after update触发器中再加代码来判断是否要移动记录,触发器的逻辑就等同于sql server中的。
      

  9. bobfang(匆匆过客) 说的好复杂噢 mislrb(aben) 你的建议我用了,还是挨个new.ani,:new.starttime,:new.endtime提示:new.ani无效的标识符
      

  10. 为什么这个触发器在这出错呢?不解select :new.* from phonedata p 提示:错误的赋值变量'NEW.'
      

  11. oracel中,在行级(for each row)触发器中是不允许对触发的表再做select/delete/update操作的。所以王长林所讲的是走不通的。
      

  12. 呵呵,这个样子,那bobfang(匆匆过客)我是不是要再建个临时表,还要再写两个触发器,也就是三个触发器,一个是把原表中的数据移到临时表,一个是把原表中的记录删除,另一个是从临时表上移动到我想移动到的表,我都有些整理不清楚了.
      

  13. insert into callend  select * from :new
      

  14. 如果可以改应用程序,那么可以改应用程序,将原先直接插入表phonedata改为调用存储过程,在那个存储过程中实现原先sql中的触发器的业务逻辑。如果不能改应用,需要建一个临时表(模仿原先sql的inserted表),建两个触发器(行级的after insert和表级的after insert)。
      

类似问题 »