我试图写一个触发器“restrict_salary”,它禁止向既不是总统也不是经理的员工颁发超过10,000美元的薪水。 如果“更新”不影响列“sal”,则不应触发触发器。在此之后,考虑使触发器禁止也增加超过9%。我尝试了一些东西但是我被卡住了,这是我的代码。
CREATE OR REPLACE TRIGGER restrict_salary
BEFORE
UPDATE OF sal
ON EMP
REFERENCING emp AS new_emp
FOR EACH ROW
WHEN (sal > 10000)
BEGIN
DECLARE job VARCHAR2(30);
select job into job from ename;
IF job!='MANAGER' OR job != 'PRESIDENT' THEN
raise_application_error (-20002, 'Cannot attribute more than 10000 dollars ');
END IF;
END;
/
答案 0 :(得分:3)
您的begin
和declare
方向错误。您必须在开始PL / SQL块之前声明变量。
我还将before update of sal on emp
更改为before update on emp
并将new.
添加到WHEN子句中,因为这是必需的。
CREATE OR REPLACE TRIGGER restrict_salary
BEFORE UPDATE ON EMP
FOR EACH ROW
WHEN (new.sal > 10000)
DECLARE
job ename.job%type;
BEGIN
-- THERE WAS A MISSING WHERE CLAUSE!!!
select job into job from ename where empid = :new.id;
IF job not in ('MANAGER', 'PRESIDENT') THEN
raise_application_error (-20002, 'Error that fit''s on page');
END IF;
END restrict_salary;
/
最大的问题是select into ...
缺少WHERE子句。这意味着如果此表中有多行,则总是会出现TOO_MANY_ROWS错误。我已经改变了,你可以看到,但你可能需要再次更改它,具体取决于你的架构。
为了清楚起见,我已将触发器的名称添加到end
语句中,并删除了不必要的referencing
子句。这两者都没有必要使其工作,但有助于提高可读性。
最后,我已将变量job
声明为您获取它的列的类型。这使您可以更改表中的列,而不会影响触发器。总是声明依赖于这样的表的变量是明智的,因为它大大减少了数据库中的更改导致的错误数量,并大大减少了代码库中的混淆。
我强烈建议您阅读the documentation以了解语法。