04098。"触发'%s。%s'无效且重新验证失败"

时间:2015-06-04 21:25:38

标签: oracle plsql

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

以下是合并后的触发器:

  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

1 个答案:

答案 0 :(得分:2)

您的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;