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