【问题标题】:04098. "trigger '%s.%s' is invalid and failed re-validation"04098. "触发器 '%s.%s' 无效并且重新验证失败"
【发布时间】:2015-06-04 21:25:37
【问题描述】:

我想编写一个触发器来阻止从表中删除记录并阻止在更新时降低工资。它可以作为两个单独的触发器很好地工作,但我想将它合并为一个。

这是我合并后的触发器:

  CREATE OR REPLACE TRIGGER test
    BEFORE DELETE OR UPDATE
    ON emp
    FOR EACH ROW
    BEGIN
      IF UPDATING THEN
        IF :NEW.sal < :OLD.sal THEN
          raise_application_error(-20500, 'You cannot decrease emp salary');
        END IF;
      ELSE DELETING THEN
        raise_application_error(-20500, 'You cannot delete records from emp');
      END IF;
    END;

问题是当我尝试更新或删除记录时出现错误:

04098. 00000 -  "trigger '%s.%s' is invalid and failed re-validation"
*Cause:    A trigger was attempted to be retrieved for execution and was
           found to be invalid.  This also means that compilation/authorization
           failed for the trigger

我认为这行有问题 - BEFORE DELETE OR UPDATE 因为我知道如果我 FOR EACH ROW 声明我应该写为 BEFORE UPDATE on sal,但是我不知道如何加入 BEFORE DELETE 声明进入这个。

编辑:
问题出在ELSE 声明附近。应该改成ELSIF

【问题讨论】:

  • 请尝试将else 替换为elsif(或删除deleting then)。
  • 你是 100% 正确的,我完全错过了。
  • 我会做任何事情来让你的触发器工作,因为它禁止减薪。 ;-)

标签: oracle plsql


【解决方案1】:

您的 IF 语句语法不正确。应该是:

CREATE OR REPLACE TRIGGER test
  BEFORE DELETE OR UPDATE
  ON emp
  FOR EACH ROW
BEGIN
  IF UPDATING AND :NEW.sal < :OLD.sal THEN
    raise_application_error(-20500, 'You cannot decrease emp salary');
  ELSIF DELETING THEN
    raise_application_error(-20500, 'You cannot delete records from emp');
  END IF;
END test;

我还将 UPDATING 案例中使用的两个 IF 语句合并为一个以使其更简单。

编辑

如果您不想让薪水减少,另一种可能的解决方案是悄悄地将薪水改回原来的值,如下所示:

CREATE OR REPLACE TRIGGER test
  BEFORE DELETE OR UPDATE
  ON emp
  FOR EACH ROW
BEGIN
  IF UPDATING AND :NEW.sal < :OLD.sal THEN
    :NEW.sal := :OLD.sal;  -- restore original salary
  ELSIF DELETING THEN
    raise_application_error(-20500, 'You cannot delete records from emp');
  END IF;
END test;

【讨论】:

  • 你是对的,但我发现触发器在更新多条记录的情况下不起作用。例如,如果我想为所有姓氏为 Johnson 的人更改 sal - WHERE emp_name = 'Johnson' 如果其中一个人的新薪水会更低,则触发器将阻止整个更新。我该如何保护?
猜你喜欢
  • 1970-01-01
  • 2012-05-15
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-10
  • 1970-01-01
相关资源
最近更新 更多