PL/SQL触发器触发问题

发布于 2024-11-01 09:41:30 字数 800 浏览 0 评论 0原文

我有一个关于 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;

但是,当我运行像触发器这样的简单语句时,

UPDATE grade SET numeric_grade = -1;

触发器不会触发。 关于如何让扳机点火有什么要点吗?

谢谢!

I have a question in regards to when a PL/SQL trigger fires.

I've written the following trigger

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;

However, when I run a simple statement like

UPDATE grade SET numeric_grade = -1;

The trigger doesn't fire.
Any points on how I can make the trigger fire?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流云如水 2024-11-08 09:41:30

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

BEFORE UPDATE ON GRADE

Your trigger is an insert trigger. Insert triggers do not fire for update statements. You should use something like this instead:

BEFORE UPDATE ON GRADE
与风相奔跑 2024-11-08 09:41:30

另外:

  1. 触发器不会阻止更新,因为您捕获触发器本身内的异常并且永远不会重新引发它,并且,
  2. 除非您使用“看到”并且正在寻找的“客户端”对于 DBMS_OUTPUT(很多都没有),您甚至不会看到 DBMS_OUTPUT.PUT_LINE 输出。

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

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

然而,对于像这样相对简单的约束,使用 CHECK 约束而不是触发器有很好的理由,例如性能、正确性、可维护性和“声明性”。

Also:

  1. The trigger will not prevent the update since you catch the exception within the trigger itself and never re-raise it, and,
  2. Unless you're using a "client" that "sees" and is looking for DBMS_OUTPUT (and many don't), you won't even see the DBMS_OUTPUT.PUT_LINE output.

To address both of these concerns, you could:

  1. Remove the exception block altogether, and,
  2. Use RAISE_APPLICATION_ERROR (with your custom error message) instead of RAISE.

However, for relatively simple constraints like these, there are good arguments for using a CHECK constraint instead of a trigger, like performance, correctness, maintainability, and "declarativeness".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文