如何使用触发器防止在oracle sql中插入数据

如何使用触发器防止在oracle sql中插入数据,sql,oracle,plsql,Sql,Oracle,Plsql,我有一个名为FACULTY的表,它有一个名为F_RANK的列,并保存char数据类型。规则是教员表中不能有超过2名教授的排名F_rank=“Full”。 因此,如果一位新教授以“Full”插入到表中,或者现有教授F_排名中的一位更新为“Full”,它应该触发一个触发器,检查具有“Full”的教授总数,如果已经是2,它应该拒绝插入 我开始为它编写触发器,但中途停了下来,因为我不知道如何处理它 这是我的密码 create or replace TRIGGER TRG_ONLYTWOPROF BEFO

我有一个名为FACULTY的表,它有一个名为F_RANK的列,并保存char数据类型。规则是教员表中不能有超过2名教授的排名F_rank=“Full”。 因此,如果一位新教授以“Full”插入到表中,或者现有教授F_排名中的一位更新为“Full”,它应该触发一个触发器,检查具有“Full”的教授总数,如果已经是2,它应该拒绝插入

我开始为它编写触发器,但中途停了下来,因为我不知道如何处理它

这是我的密码

create or replace TRIGGER TRG_ONLYTWOPROF
BEFORE INSERT OR UPDATE OF F_RANK ON FACULTY
DECLARE 
TOTAL NUMBER(4);
BEGIN
SELECT COUNT(F_RANK) INTO TOTAL 
FROM FACULTY
WHERE F_RANK = 'Full';
IF :NEW.F_RANK = 'Full' THEN
-- check if total is less than 2
   -- if it is, accept insertion
   -- else reject insertion of the row
ELSE
-- accept insertion of the row
-- or accept update of existing row on F_RANK column
END;
/
有人能帮我吗?
提前谢谢。

你真的离得不远。您正确地看到触发器不能是行触发器,因为您需要查询定义了触发器的表。我建议如下:

create or replace TRIGGER TRG_ONLYTWOPROF
  AFTER INSERT OR UPDATE OF F_RANK ON FACULTY
DECLARE 
  TOTAL NUMBER(4);
BEGIN
  SELECT COUNT(*)
    INTO TOTAL 
    FROM FACULTY
    WHERE F_RANK = 'Full';

  IF TOTAL > 2 THEN
    RAISE_APPLICATION_ERROR(-20001, 'Failure in trigger TR_ONLYTWOPROF: two professors with RANK=''Full'' already exist');
  END IF;
END TRG_ONLYTWOPROF;
这定义了一个语句触发器,它将在插入或更新发生后触发。一个问题是语句触发器看不到行值,因此如果新行的F_秩不是“Full”,则不能跳过检查。这不重要,但必须牢记在心。另一个原因是,由于看不到行值,因此需要在语句生效后执行检查,以便正确引发异常


祝你好运。

你能更新教员的表格结构吗?解决方案必须使用触发器吗?有时,使用快速刷新的物化视图可以更好地解决这些问题。我认为,如果两个会话更新不同的行,然后两个会话都提交,那么这将不起作用。会话无法看到彼此的更新。答案是更加锁定。