编写一个触发器,当修改EMP表中的工资(SAL)时,保证10号部门不超过5000元,其他部门不超过7000元~~~~~~~~~~

解决方案 »

  1.   

    CREATE OR REPLACE TRIGGER TR_SAL_LIMIT 
    BEFORE INSERT OR UPDATE 
    ON SCOTT.emp
    FOR EACH ROW 
    DECLARE
    v_comm NUMBER;
    v_comm_else NUMBER;
    v_sal NUMBER;
    v_sal_else NUMBER;
    BEGIN 
      SELECT SUM(comm) INTO v_comm FROM emp WHERE DEPTNO=10;
      IF v_comm=NULL THEN
         v_comm :=0;
      END IF;
      SELECT SUM(comm) INTO v_comm_else FROM EMP WHERE DEPTNO<>10;
      IF v_comm_else=NULL THEN
         v_comm_else :=0;
      END IF;
      SELECT SUM(sal) INTO v_sal FROM emp WHERE DEPTNO=10;
      IF v_sal=NULL THEN
         v_sal :=0;
      END IF;
      SELECT SUM(sal) INTO v_sal_else FROM emp WHERE DEPTNO<>10;
      IF v_sal_else=NULL THEN
         v_sal_else :=0;
      END IF;
      IF (v_comm+v_sal+:NEW.comm+:NEW.sal)>5000 OR (v_comm_else+v_sal_else+:NEW.comm+:NEW.sal)>7000 THEN
         Raise_application_error(-21000,'error');
      END IF;
    END;
    -----------------------------------------------------------
    贴了个图,但是没用,只好粘代码。
    因为原表里有字段值为null 的情况,而null参与运算是没有任何意义的。因此我先把部门号为10和其余部门COMM的总和算出来,以及把部门号为10和其余部门的sal 总和算出来。然后判断这个总和是否为空。之后再进行运算。 对于这个判断,有考虑过建立数组或者游标逐条判断,但是发现远不如这个省事。
    也可以把代码分为procedure和trigger,在trigger里调用procedure即可。
    小测了下, 应该没什么问题。但是不知道是否是最好的办法。
      

  2.   

    没注意看,原来是scott.emp下的练习啊
    楼上的思路很对,不过有些地方需要改下,首先,判断是否为空应该是is null或者is not null,不会用=
    这种触发器最不好的地方,就是每插入一行,都要进行对全表的一次搜索。这里的select sum() from emp where deptno<>10和deptno=10,改成按:new.deptno来判断更好一些
    不错不错
      

  3.   


    是应该 用 is null,没注意。改成select sum() from emp where deptno<>10和deptno=10,改成按:new.deptno来判断,这个灵活性好点。