PL/SQL触发器触发问题

use*_*330 2 sql oracle triggers plsql

关于何时触发PL/SQL触发器,我有一个问题.

我写了以下触发器

CREATE OR REPLACE TRIGGER gradeInputCheck
BEFORE INSERT ON GRADE 
FOR EACH ROW
DECLARE
  newGrade GRADE.NUMERIC_GRADE%TYPE := :NEW.NUMERIC_GRADE;
    grade_too_low EXCEPTION;
    grade_too_high EXCEPTION;
BEGIN
  DBMS_OUTPUT.PUT_LINE(newGrade);
    IF (newGrade < 0) THEN
        RAISE grade_too_low;
    ELSIF (newGrade > 100) THEN
        RAISE grade_too_high;
    END IF;
EXCEPTION
    WHEN grade_too_low THEN
        DBMS_OUTPUT.PUT_LINE('Grades must be between 0 and 100');
    WHEN grade_too_high THEN
        DBMS_OUTPUT.PUT_LINE('Grades must be between 0 and 100');
END;
Run Code Online (Sandbox Code Playgroud)

但是,当我运行一个简单的语句时

UPDATE grade SET numeric_grade = -1;
Run Code Online (Sandbox Code Playgroud)

触发器不会触发.关于如何使触发器触发的任何要点?

谢谢!

Tom*_*mmi 10

您的触发器是插入触发器.插入触发器不会触发更新语句.你应该使用这样的东西:

BEFORE UPDATE ON GRADE
Run Code Online (Sandbox Code Playgroud)


Bri*_*ire 9

也:

  1. 触发器不会阻止更新,因为您在触发器本身内捕获异常并且从不重新引发它,并且,
  2. 除非你使用"看到" 并且正在寻找DBMS_OUTPUT 的"客户端" (许多人没有),否则你甚至不会看到DBMS_OUTPUT.PUT_LINE输出.

要解决这两个问题,您可以:

  1. 完全删除异常块,并且,
  2. 使用RAISE_APPLICATION_ERROR(带有自定义错误消息)而不是RAISE.

但是,对于像这样的相对简单的约束,使用CHECK约束而不是触发器(如性能,正确性,可维护性和"声明性")有很好的参数.