使用来自同一个表的变量获取值来创建更新触发器的正确​​方法是什么?

时间:2017-11-16 21:30:30

标签: oracle plsql sql-update database-trigger

我正在创建一个更新触发器,员工的薪水永远不会高于总统。但是,我需要将总统的薪水用于比较,以及" new"更新了员工的工资。

我最初使用from employees表中的子查询,但由于表变异问题而不得不创建一个新表。我不认为创建新表是真正实现的合理解决方案。

有没有办法可以在不创建新桌子的情况下节省总统薪水?

CREATE OR REPLACE TRIGGER prevent_salary 
BEFORE UPDATE ON employees
FOR EACH ROW 
    declare pres_sal number(8,2);
BEGIN 
    select salary into pres_sal from employees_salary where job_id='AD_PRES';--employees_salary was employees but that gives mutating error

    IF (:new.salary > pres_sal)
        THEN UPDATE employees 
        SET salary = :old.salary
        WHERE employee_id = :old.employee_id;
    END IF;
END;

2 个答案:

答案 0 :(得分:1)

你可以试试这个:

CREATE OR REPLACE TRIGGER prevent_salary 
BEFORE UPDATE ON employees
FOR EACH ROW 
    declare pres_sal number(8,2);
BEGIN 
    select salary into pres_sal from employees_salary where job_id='AD_PRES';--employees_salary was employees but that gives mutating error

    IF (:new.salary > pres_sal)
     Raise_Application_Error (-20101, 'An employee''s salary couldn''t exceed president''s !');
    END IF;
END;

答案 1 :(得分:1)

一种方法是在BEFORE STATEMENT触发器中保存总统的薪水,然后在FOR EACH ROW触发器中使用它。

“复合触发器”,至少从版本11.1开始,在一个地方提供了一种很好的方法。

以下是一个例子:

CREATE OR REPLACE TRIGGER prevent_salary 
FOR UPDATE OF salary ON employees
COMPOUND TRIGGER

  pres_sal NUMBER;

BEFORE STATEMENT IS
BEGIN
    select salary 
    into pres_sal 
    from employees 
    where job_id='AD_PRES';
END BEFORE STATEMENT;

BEFORE EACH ROW IS 
BEGIN 
    :new.salary := least(:new.salary, pres_sal);
END BEFORE EACH ROW;

END prevent_salary;