【问题标题】:Error while executing insert triggers in PL/SQL [duplicate]在 PL/SQL 中执行插入触发器时出错 [重复]
【发布时间】:2019-10-11 05:28:45
【问题描述】:

执行 PL/SQL 时出现以下错误 这里我们使用 2 个变量来存储薪水 'x' 和 'y'。

Error report -
ORA-04091: table SXP180107.EMPLOYEE is mutating, trigger/function may not see it
ORA-06512: at "SXP180107.CHECK_SAL", line 5
ORA-04088: error during execution of trigger 'SXP180107.CHECK_SAL'



create TRIGGER Check_sal
 AFTER INSERT OR UPDATE OF Salary ON EMPLOYEE
FOR EACH ROW
DECLARE
 X NUMBER;
 Y NUMBER;
 BEGIN
 select SALARY into X from Employee where SSN=:NEW.SSN;
 select SALARY into Y from Employee E, Department D where E.Dno = D.Dno and E.Ssn = D.Mgrssn;

 IF (X > Y)
 THEN
   dbms_output.put_line('error');
 -- RAISE_APPLICATION_ERROR( -20001, 'The new Salary shouldnt be greater than mgr salary' );
 END IF;
END;




insert into employee values('John','B','Smith','123456700',TO_DATE('1955-01-9','YYYY-MM-DD'),'731 Fondren, Houston, TX','M',100,'333445555',5);

当我尝试插入数据时,我遇到了这些错误。

【问题讨论】:

    标签: sql oracle plsql database-trigger


    【解决方案1】:

    我不确定我是否愿意为那个雇主工作。我的薪水只能越来越低。

    无论如何:为什么不只是

    create or replace trigger check_sal
      before update of salary on employee
      for each row
    begin
      if :new.salary > :old.salary then
         raise_application_error(-20001, 'The new Salary shouldnt be greater than old Salary');
      end if;
    end;
    

    您不能查询正在修改的表,但您可以使用伪记录。

    此外,第二个select 没有多大意义。我想它无论如何都会提高too-many-rows,因为它没有受到足够的限制。


    [编辑,阅读 cmets 后]

    第二次选择用于查找经理工资,如果员工工资大于经理工资,则会引发错误。

    你为什么没有在问题中这么说?就像你最初所说的那样,员工的新薪水似乎不能高于他们自己的旧薪水。

    好的,这是修改后的代码。看看有没有帮助。由于变异表错误,我正在使用复合触发器。

    测试表:

    SQL> create table employee as select deptno, empno, ename, mgr, sal from emp;
    
    Table created.
    

    触发器:

    SQL> create or replace trigger check_sal
      2    for insert or update on employee
      3    compound trigger
      4
      5    type t_ch_tab is table of employee%rowtype;
      6    g_ch_tab      t_ch_tab := t_ch_tab();
      7
      8    after each row is
      9    begin
     10      g_ch_tab.extend;
     11      g_ch_tab(g_ch_tab.last).empno  := :new.empno;
     12      g_ch_tab(g_ch_tab.last).mgr    := :new.mgr;
     13      g_ch_tab(g_ch_tab.last).sal    := :new.sal;
     14    end after each row;
     15
     16
     17    after statement is
     18      l_sal employee.sal%type;
     19    begin
     20      for i in g_ch_tab.first .. g_ch_tab.last loop
     21        select e.sal
     22          into l_sal
     23          from employee e
     24          where e.empno = g_ch_tab(i).mgr;
     25
     26        if g_ch_tab(i).sal > l_sal then
     27           raise_application_error(-20001, 'Employee''s salary can not be higher than manager''s salary');
     28        end if;
     29      end loop;
     30    end after statement;
     31  end check_sal;
     32  /
    
    Trigger created.
    

    测试:表格内容:

    SQL> select * From employee order by deptno, ename;
    
        DEPTNO      EMPNO ENAME             MGR        SAL
    ---------- ---------- ---------- ---------- ----------
            10       7782 CLARK            7839       2450
            10       7839 KING                       10000
            10       7934 MILLER           7782       1300
            20       7876 ADAMS            7788       1100
            20       7902 FORD             7566       3000     --> manager
            20       7566 JONES            7839       2975
            20       7788 SCOTT            7566       3000     
            20       7369 SMITH            7902        920     --> employee
            30       7499 ALLEN            7698       1600
            30       7698 BLAKE            7839       2850
            30       7900 JAMES            7698        950
            30       7654 MARTIN           7698       1250
            30       7844 TURNER           7698       1500
            30       7521 WARD             7698       1250
    
    14 rows selected.
    

    让我们更新和插入(先失败):

    SQL> -- SMITH works in DEPTNO = 20 whose MGR = FORD and his salary is 3000. No employee whose
    SQL> -- boss is FORD should have salary higher than 3000
    SQL>
    SQL> update employee set sal = 10000 where ename = 'SMITH';
    update employee set sal = 10000 where ename = 'SMITH'
           *
    ERROR at line 1:
    ORA-20001: Employee's salary can not be higher than manager's salary
    ORA-06512: at "SCOTT.CHECK_SAL", line 25
    ORA-04088: error during execution of trigger 'SCOTT.CHECK_SAL'
    
    
    SQL>
    SQL> insert into employee(deptno, empno, ename, mgr, sal) values
      2  (20, 1, 'LF', 7902, 10000);
    insert into employee(deptno, empno, ename, mgr, sal) values
                *
    ERROR at line 1:
    ORA-20001: Employee's salary can not be higher than manager's salary
    ORA-06512: at "SCOTT.CHECK_SAL", line 25
    ORA-04088: error during execution of trigger 'SCOTT.CHECK_SAL'
    

    成功(因为工资低于3000):

    SQL> update employee set sal = 2000 where ename = 'SMITH';
    
    1 row updated.
    

    【讨论】:

    • 第二次选择用于查找经理工资,如果员工工资大于经理工资,则会引发错误。
    • 啊哈。好的,我已经编辑了我的答案。请看一下。
    • 当然,@a_horse!我在想什么……这就是 OP 最初抱怨的。呸!谢谢你。希望 - 已修复。
    • 谢谢你的作品
    • 我的员工和部门是 2 个不同的表,我想在员工更新时触发
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多