0

我正在尝试编写一个触发器“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;
/
4

1 回答 1

3

你有begindeclare错误的方式。您必须先声明变量,然后才能开始 PL/SQL 块。

我还更改before update of sal on empbefore 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 .... 这意味着如果您在此表中有不止一行,您总是会收到 TOO_MANY_ROWS 错误。如您所见,我已经更改了它,但您可能需要再次更改它,具体取决于您的架构。

为了清楚起见,我在end语句中添加了触发器的名称并删除了不必要的referencing子句。这两者对于使其工作都是不必要的,但有助于提高可读性。

最后,我已将变量声明job为您从中获取它的列的类型。这使您可以更改表中的列,而完全不影响触发器。始终声明依赖于这样的表的变量是明智的,因为它大大减少了由数据库更改引起的错误数量,并大大减少了代码库中的混淆。

我强烈建议阅读文档以了解语法。

于 2012-11-11T22:31:38.190 回答