首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >行上的DML触发器

问行上的DML触发器
EN

Stack Overflow用户
提问于 2012-11-12 05:44:07
回答 1查看 100关注 0票数 0

我正在尝试写一个触发器"restrict_salary“,它禁止向既不是总裁也不是经理的员工发放超过10,000美元的薪水。如果"update“不影响列"sal”,则不应触发触发器。之后,正在考虑使触发器禁止也增加了9%以上。我已经尝试了一些东西,但我卡住了,这是我的代码。

代码语言:javascript
复制
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;
/
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-12 06:31:38

你让begin和declare走错了路。您必须先声明变量,然后才能开始PL/SQL块。

我还将before update of sal on emp更改为before update on emp,并根据需要将new.添加到WHEN子句中。

代码语言:javascript
复制
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来理解它的语法。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13335781

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档