2012-11-11 54 views
0

我正在尝试编写触发器“restrict_salary”,该触发器禁止向既不是总裁也不是经理的员工发放超过10,000美元的薪水。 如果“更新”不影响列“sal”,则不应触发触发器。之后,正考虑制定触发条件,禁止增加9%以上。我试了一些东西,但我卡住了,这是我的代码。连续触发DML

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

你会收到错误信息吗?如果是这样,请编辑您的问题以包含它们。祝你好运。 – shellter

+0

提醒我不要为你的公司工作...他们是吝啬鬼(或不在加利福尼亚州)。 –

+0

如何参考老旧AS(老薪水的价值)? –

回答

3

你有begindeclare以错误的方式。您必须先声明变量,然后才能开始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以获得对语法的理解。

+0

感谢Ben,你已经解决了我的问题。对此,我真的非常感激。 – sully11

相关问题