如何在同一个表上查询和执行触发器

时间:2012-10-05 20:32:35

标签: oracle triggers

希望有人可以帮忙解决这个问题。我是触发器的新手,我正在尝试创建一个触发器,检查被修改的记录是否具有特定值。

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

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

如果有人试图修改Val,则触发器应该停止它 我创建了以下触发器:

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这是“表格文件正在变异,触发器/功能可能看不到它”

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

我感谢任何帮助

2 个答案:

答案 0 :(得分: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'

答案 1 :(得分: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'