我有一个表触发器,当状态从2变为3时,它调用一个过程。该过程检查整个数据组(Group_id)是否处于状态3,然后执行一些操作。
但现在我面临的问题是,当我同时将整个数据组设置为状态3时,该过程会被多次调用,并多次执行此操作。我怎么才能防止他的?例如,使用锁
下面是我的过程查询:
SELECT COUNT(*)
INTO nResult
FROM ticket
WHERE group_id = nGroupId
AND statusid BETWEEN 0 AND 2;
/* If not all tickets of group in status 3, no action required */
IF nResult != 0 THEN
RETURN;
END IF;这是我的触发器:
IF (:NEW.STATUSID = 3 AND :OLD.STATUSID = 2) THEN
myprocedure(:NEW.group_id);
END IF;发布于 2016-07-14 22:46:32
您可能有一个行级触发器,该触发器在每次更新行时触发;例如:
SQL> create table trigger_table(status number);
Table created.
SQL> insert into trigger_table values (1);
1 row created.
SQL> insert into trigger_table values (2);
1 row created.
SQL> insert into trigger_table values (3);
1 row created.
SQL> create trigger update_trigger
2 after update on trigger_table
3 for each row /* ROW LEVEL */
4 begin
5 dbms_output.put_line('change');
6 end;
7 /
Trigger created.
SQL> set serveroutput on
SQL> update trigger_table set status = 1;
change
change
change
3 rows updated.您需要一个表级触发器,在每次update语句之后触发:
SQL> create or replace trigger update_trigger
2 after update on trigger_table
3 begin
4 dbms_output.put_line('change');
5 end;
6 /
Trigger created.
SQL> update trigger_table set status = 1;
change
3 rows updated.Here你会发现更多的东西。
正如Nicholas Krasnov正确地观察到的那样,在这种触发器中,考虑到一组行而不是单个行,您没有:new或:old值。有一种方法可以满足您的需求,但这是一个棘手的解决方案,在用于生产环境之前,我会仔细检查它。
您可以创建一个信号量表,以了解是否必须触发触发器,然后使用两个触发器,一个在行级,在更新之前,另一个在表级,在更新之后;行级触发器检查值并更新信号量表,而表级1,在更新之后触发,读取信号量,调用您的过程,如果需要,然后重置信号量。例如:
SQL> create table trigger_table(status number);
Table created.
SQL> insert into trigger_table values (1);
1 row created.
SQL> insert into trigger_table values (2);
1 row created.
SQL> insert into trigger_table values (3);
1 row created.
SQL> create table checkChange (fire varchar2(3));
Table created.
SQL> insert into checkChange values ('NO');
1 row created.
SQL> create or replace trigger before_update_trigger
2 before update on trigger_table
3 for each row /* ROW LEVEL */
4 begin
5 if :new.status = 3 and :old.status = 2 then
6 update checkChange set fire = 'YES';
7 end if;
8 end;
9 /
Trigger created.
SQL> create or replace trigger after_update_trigger
2 after update on trigger_table
3 declare
4 vFire varchar2(3);
5 begin
6 select fire
7 into vFire
8 from checkChange;
9 if vFire = 'YES' then
10 dbms_output.put_line('change');
11 update checkChange set fire = 'NO';
12 end if;
13 end;
14 /
Trigger created.
SQL> update trigger_table set status = 2;
3 rows updated.
SQL> update trigger_table set status = 3;
change
3 rows updated.
SQL>https://stackoverflow.com/questions/38376965
复制相似问题