plsql:如何使用语句级触发器编写此触发器?

时间:2019-04-04 23:08:58

标签: oracle plsql database-trigger

从昨天开始,我一直在尝试解决此问题,但我不知道如何编写一个执行此任务的工作语句级触发器。

这是问题:

实施并全面测试可验证 遵循一致性约束。

“一个职位最多需要四个技能”。

准备好后,保存CREATE TRIGGER语句和所有 在脚本solution3.sql中全面测试触发器。全面的测试意味着触发器必须拒绝违反一致性约束的SQL语句,并接受不违反一致性约束的SQL语句。查找应测试哪些SQL语句是您任务的一部分。每当SQL语句违反一致性约束时,触发器都必须返回ORA-…错误消息。使用过程RAISE_APPLICATION_ERROR返回ORA-…错误消息。如果SQL语句未违反一致性约束,则触发器必须返回no 消息。

如果您想尝试一下此示例,请参见以下数据库文件:https://www.dropbox.com/sh/4dyemye2bpq5hv4/AAAEAmTDELHcgFFhpfRrqHtDa?dl=0

我编写的代码给我一个错误,即新旧版本不能在表级触发器上使用,而且我认为如果我将其设置为行级触发器,但需要将其用作语句触发器,此函数将起作用。你能告诉我我做错了吗?

create or replace trigger checkskillnum
before insert or update of pnumber on sneeded
declare
skillnum number;
begin
select count(*) into skillnum from sneeded where sneeded.pnumber = :new.pnumber;
if skillnum > 3 then
RAISE_APPLICATION_ERROR(-20030,'A position does not need more than 4 skills');
end if;
end;
/

结果应仅允许插入或更新仅Skillnum小于4的那些语句。 但现在它符合错误:新旧表不能在表级触发器上使用。

新解决方案:

需要的表格: select语句的第一个结果为4,即使pnumber不同,触发器也会检查该结果。

SQL> select pnumber, count(*) as SKILL_COUNT
  2                   from sneeded
  3                   group by pnumber
  4                   order by COUNT(*) DESC
  5  ;

   PNUMBER SKILL_COUNT
---------- -----------
         1           4
         2           3
         3           3
         7           3
         5           3
         6           1
         4           1

7 rows selected.

新解决方案中的错误:

SQL> insert into sneeded values(1,'fishing',7);
insert into sneeded values(1,'fishing',7)
            *
ERROR at line 1:
ORA-20030: A position does not need more than 4 skills
ORA-06512: at "SYSTEM.CHECKSKILLNUM", line 8
ORA-04088: error during execution of trigger 'SYSTEM.CHECKSKILLNUM'


SQL> insert into sneeded values(2,'fishing',7);
insert into sneeded values(2,'fishing',7)
            *
ERROR at line 1:
ORA-20030: A position does not need more than 4 skills
ORA-06512: at "SYSTEM.CHECKSKILLNUM", line 8
ORA-04088: error during execution of trigger 'SYSTEM.CHECKSKILLNUM'


SQL> insert into sneeded values(4,'fishing',7);
insert into sneeded values(4,'fishing',7)
            *
ERROR at line 1:
ORA-20030: A position does not need more than 4 skills
ORA-06512: at "SYSTEM.CHECKSKILLNUM", line 8
ORA-04088: error during execution of trigger 'SYSTEM.CHECKSKILLNUM'

1 个答案:

答案 0 :(得分:0)

一个语句触发器(一个没有FOR EACH ROW的触发器)不能使用:OLD:NEW,因为它无法访问行值。但是在这种情况下,您实际上并不需要它们-您只需要以不同的方式思考即可。

您关心的是-语句执行后,是否有任何具备三种以上技能的人?因此,您需要弄清楚如何找到这些信息。

以下应为您做到:

create or replace trigger checkskillnum
  before insert or update on sneeded
begin
  FOR aRow IN (select pnumber, count(*) as SKILL_COUNT
                 from sneeded 
                 group by pnumber
                 order by COUNT(*) DESC)
  LOOP
    IF aRow.SKILL_COUNT > 3 THEN
      RAISE_APPLICATION_ERROR(-20030, 'A position does not need more than 4 skills');
    END IF;

    EXIT;    -- The first row will have the highest SKILL_COUNT, so only need to  
  END LOOP;  -- check the first row.
end CHECKSKILLNUM;

好运。