我有以下触发更新操作。
CREATE OR REPLACE TRIGGER oferta_trigger
BEFORE UPDATE ON oferty
FOR EACH ROW
DECLARE
id_oferta number (10);
id_komis number (10);
id_test_komis number (10);
suma decimal(10,2) :=0;
CURSOR c1 IS
SELECT cena_aktualna, id_test_komis
FROM oferty
WHERE status = 'A';
BEGIN
id_oferta := :NEW.idk;
dbms_output.put_line(id_oferta);
SELECT komis_id INTO id_komis FROM oferty WHERE idk = id_oferta;
FOR i in c1 LOOP
IF i.id_test_komis = id_komis THEN
suma := suma + i.cena_aktualna;
END IF;
END LOOP;
UPDATE komisy SET wartosc_samochodow = suma WHERE idk = id_komis;
END;
在更新操作期间。
UPDATE oferty SET status ='Z' WHERE idk =1;
我收到以下错误:
SQL错误:ORA-04091:表OFERTY正在变异,触发器/函数可能 看不到它。
如何解决问题。我认为这是获得身份证的问题。
答案 0 :(得分:3)
以下是基于Scott模式的示例。我更改了DEPT表,添加了一个新列(SUM_SAL),该列应该包含该部门所有工资的总和。
首先,好的,旧的变异表方式。
SQL> create or replace trigger trg_sumsal
2 after update on emp
3 for each row
4 declare
5 l_sum number;
6 begin
7 select sum(sal) into l_sum
8 from emp
9 where empno = :new.empno;
10
11 update dept set sum_sal = l_sum
12 where deptno = :new.deptno;
13 end;
14 /
Trigger created.
SQL> update emp set sal = 5000 where ename = 'KING';
update emp set sal = 5000 where ename = 'KING'
*
ERROR at line 1:
ORA-04091: table SCOTT.EMP is mutating, trigger/function may not see it
ORA-06512: at "SCOTT.TRG_SUMSAL", line 4
ORA-04088: error during execution of trigger 'SCOTT.TRG_SUMSAL'
SQL>
正如我们已经知道的那样,这是行不通的。
现在,复合触发器:
SQL> create or replace trigger trg_sumsal
2 for update or insert on emp
3 compound trigger
4
5 l_deptno emp.deptno%type;
6
7 after each row is
8 begin
9 l_deptno := :new.deptno;
10 end after each row;
11
12 after statement is
13 l_sum number;
14 begin
15 select sum(sal) into l_Sum
16 from emp
17 where deptno = l_deptno;
18
19 update dept set sum_sal = l_sum
20 where deptno = l_deptno;
21 end after statement;
22 end;
23 /
Trigger created.
SQL> update emp set sal = 10000 where ename = 'KING';
1 row updated.
SQL> select * From dept;
DEPTNO DNAME LOC SUM_SAL
---------- -------------- ------------- ----------
10 ACCOUNTING NEW YORK 13750
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
尼斯;这有效!
[编辑,阅读威廉的评论后]
如果在单个UPDATE语句中影响了多个部门,则上述代码将无法正常运行。略微调整,它看起来像这样&解决了这个问题:
SQL> create or replace trigger trg_sumsal
2 for update or insert on emp
3 compound trigger
4
5 type t_tab is table of number;
6 l_tab t_tab := t_tab();
7
8 after each row is
9 begin
10 l_tab.extend;
11 l_tab(l_tab.last) := :new.deptno;
12 end after each row;
13
14 after statement is
15 l_sum number;
16 begin
17 for i in l_tab.first .. l_tab.last loop
18 select sum(sal) into l_Sum
19 from emp
20 where deptno = l_tab(i);
21
22 update dept set sum_sal = l_sum
23 where deptno = l_tab(i);
24 end loop;
25 end after statement;
26 end;
27 /
Trigger created.
测试:
SQL> select * from dept;
DEPTNO DNAME LOC SUM_SAL
---------- -------------- ------------- ----------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> update emp set sal = 10000 where ename in ('SMITH', 'KING');
2 rows updated.
SQL> select * from dept;
DEPTNO DNAME LOC SUM_SAL
---------- -------------- ------------- ----------
10 ACCOUNTING NEW YORK 13750
20 RESEARCH DALLAS 15975
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>