将语句级触发器转换为行级触发器

时间:2019-11-14 09:51:20

标签: oracle plsql database-trigger

我正在尝试在Workson表上创建触发器,当我尝试插入到Workson表中时,该触发器将更新员工的total_budget。下面的代码有效,但我需要将此语句触发器更改为行级触发器

CREATE OR REPLACE TRIGGER updateEmp
after INSERT
   ON workson
BEGIN
    FOR emp_l IN (select employee.e# AS employeeNo,sum(budget) AS totalbudget
                from employee left outer join workson
                on employee.e# = workson.e#
                left outer join project
                on workson.p# = project.p#
                group by employee.e#
                order by employee.e# asc)
    LOOP
        UPDATE employee
           SET total_budget = emp_l.totalbudget
         WHERE e# = emp_l.employeeNo;
    END LOOP;
END;

我在下面尝试使用此触发器,但是由于提交的第一个插入直到提交下一个插入才发生,所以它无法正常工作

CREATE OR REPLACE TRIGGER updateEmp
after INSERT
   ON workson
for each row
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN

    FOR emp_l IN (select employee.e# AS employeeNo,sum(budget) AS totalbudget
                from employee left outer join workson
                on employee.e# = workson.e#
                left outer join project
                on workson.p# = project.p#
                group by employee.e#
                order by employee.e# asc)
    LOOP
        UPDATE employee
           SET total_budget = emp_l.totalbudget
         WHERE e# = emp_l.employeeNo;
    END LOOP;
commit;
END;

insert into workson(e#,p#,hours)
values('00187','1005',20);
commit;
insert into workson(e#,p#,hours)
values('00187','1006',20);
commit;

1 个答案:

答案 0 :(得分:0)

作为行级触发器,根据定义,它将只有一个E#和预算小时,这足以更新员工。不需要选择预算。只需直接更新员工。

create or replace trigger 
after insert
   on workson
for each row
declare
begin
    update employee
       set total_budget = total_budget + :new.budget 
     where e# = :new.e#;
end ;

您不想要AUTONOMOUS_TRANSACTION。当您在触发器中更新employee并提交该雇员,然后触发该触发器的插入被回滚时会发生什么。该雇员的更新仍在执行。
现在,从讲师的角度来看,也许作业的目的是显示它们之间的数据需求和可用性。