2012-10-05 43 views
0

希望有人能帮助解决这个问题。我是触发器的新手,我试图创建一个触发器来检查被修改的记录是否具有特定的值。如何在同一张表上查询和执行触发器

示例 我有一个表称为归档具有filing_id和filing_status,我想阻止某人更新或删除该表中的任何记录具有filing_status =“FILED”。 所以,如果我有以下

Filing_id Filing_status Val 
--------- ------------- --- 
0    Filed   X 

如果有人试图修改瓦尔触发器应停止 我创建了以下触发:

CREATE or replace TRIGGER TRG_PREV_FILING 
    BEFORE DELETE or UPDATE 
    ON PF.FILING 
    FOR EACH ROW 
    declare 
    rowcnt number; 
    BEGIN 
    SELECT COUNT(filing_id) INTO rowcnt FROM PF.FILING 
     where status = 'FILED' 
     and filing_id = :new.filing_id; 
    if (rowcnt > 0) 
    then 
     raise_application_error (-20100, 'You can not delete Or Update initial record'); 
    end if; 
    END; 

我面对的是我得到的问题: ORA-04091这是“表格归档突变,触发器/函数可能看不到它”

所以基本上我不能查询在同一张表上,我正在执行触发器?这是我的情况的问题,有没有人知道这方面的工作?

我感谢所有帮助

回答

3

您不必查询表触发射击上能够做这种检查。您可以使用:old获得正在修改的列的值。这里有一个例子:

SQL> create table filing(
    2 status varchar2(31), 
    3 val number 
    4 ); 

Table created 


SQL> create or replace trigger TRG_FILING before delete or update on FILING 
    2 for each row 
    3 begin 
    4 if lower(:old.status) = 'filed' 
    5 then 
    6  raise_application_error(-20000, 'You cannot delete or modify this record'); 
    7 end if; 
    8 end; 

SQL>/

Trigger created 


SQL> insert into FILING values('FILED', null); 

1 row inserted 

SQL> insert into filing values('OK', 1); 

1 row inserted 

SQL> commit; 

Commit complete 

SQL> select * 
    2 from filing; 

STATUS         VAL 
------------------------------- ---------- 
FILED       
OK          1 

SQL> delete 
    2 from filing 
    3 where val is null; 


ORA-20000: You cannot delete or modify this record 
ORA-06512: at "HR.TRG_FILING", line 4 
ORA-04088: error during execution of trigger 'HR.TRG_FILING' 
+0

非常感谢。我必须学习更多关于触发器的知识。 – user955165

0

最基本的一点是,你应该设计你的数据库的方式,在不触发基于更新/删除的行了验证。如果你有几行同一个filing_id,那么你可以过度劳累你的数据库设计。也许你真的只是检查自己的桌子,在这种情况下,你可以使用:old。但是,当你有几行检查(我假设你是做一个计数),那么你必须使用两个表。这是一个建议。

create table filing_status (filing_id number, status varchar2(10)); 
create table filing_content (filing_id number, content_id number, content varchar2(200)); 
CREATE or replace TRIGGER TRG_PREV_FILING 
    BEFORE DELETE or UPDATE 
    ON FILING_content 
    FOR EACH ROW 
    declare 
    rowcnt number; 
    BEGIN 
    SELECT COUNT(filing_id) INTO rowcnt FROM FILING_status 
     where status = 'FILED' 
     and filing_id = :new.filing_id; 
    if (rowcnt > 0) 
    then 
     raise_application_error (-20100, 'You can not delete Or update filed record'); 
    end if; 
    END; 
/
insert into filing_status values (1, 'FILING'); 
insert into filing_content values (1, 1, 'foo'); 
insert into filing_content values (1, 2, 'bar'); 
insert into filing_status values (1, 'FILED'); 
update filing_content set content = 'bahr' where filing_id = 1 and content_id = 2; 

ERROR at line 1: 
ORA-20100: You can not delete Or update filed record 
ORA-06512: at "DEMO.TRG_PREV_FILING", line 9 
ORA-04088: error during execution of trigger 'DEMO.TRG_PREV_FILING' 
相关问题