插入后在同一个表上插入触发器

时间:2016-08-20 08:05:31

标签: oracle plsql triggers

CREATE TABLE STUDENTS_1
(
NAME VARCHAR2(50)NOT NULL,
DIV VARCHAR2(5) CHECK (DIV IN ('E','F','G')),
MARKS NUMBER CHECK (MARKS <= 600),
GRADE VARCHAR2(5) CHECK (GRADE IN ('A','B','C'))
)
CREATE OR REPLACE TRIGGER MARKS 
BEFORE INSERT OR UPDATE ON STUDENTS_1
FOR EACH ROW 


BEGIN

IF (:NEW.MARKS>500)THEN 
INSERT INTO STUDENTS_1(MARKS,GRADE)VALUES(:NEW.MARKS,'A');

ELSIF (:NEW.MARKS>400 AND:NEW.MARKS<500) THEN 
INSERT INTO STUDENTS_1(MARKS,GRADE)VALUES(:NEW.MARKS,'B');

ELSE (:NEW.MARKS <400 )
INSERT INTO STUDENTS_1(MARKS,GRADE)VALUES(:NEW.MARKS,'C');


END IF ;
END;/

我会在此表格中插入标记,并且我希望触发器相应地触发等级到相同的表格中,这与我进入的标记有关,并且我在{i =}时获得not enough values error。这样做 所以我想知道我在做什么是可能还是有其他方式?

1 个答案:

答案 0 :(得分:3)

这种方法存在一些问题。首先,如果你可以在students_1的插入触发器中插入students_1,你就会创建一个无限循环。你会做一个插入,触发触发器,它会做一个插入,它会触发触发器,这会触发,它会触发触发器......其次,你可能想要设置grade当前行的值,而不是创建新行。 grade可能与您在插入过程中的行的mark有关。

您可能只想更新grade伪记录中的:new

FOR EACH ROW
BEGIN
  case when :new.marks < 400
       then :new.grade := 'C';
       when :new.marks between 400 and 500
       then :new.grade := 'B';
       when :new.marks > 500
       then :new.grade := 'A';
   end case;
END;

如果这是一个真正的问题,而不是需要触发器的家庭作业,你可能需要grade的虚拟列,其中包括计算而不是编写触发器来维护计算列。