【问题标题】:PL/SQL Trigger to sum rows and update other rowsPL/SQL 触发器对行求和并更新其他行
【发布时间】:2014-03-06 19:53:40
【问题描述】:

我尝试了以下操作:

编写一个触发器,使一个部门的预算是支付给该部门员工的工资总和(请记住,员工只在一个部门工作的时间百分比)。 DEPT 表包括 Dept ID (Did)、Budget、ManagerID,Employee(EMP) 表包括 EMPID(eid)、SALARY、BONUS、AGE 和 WORKS 表包括 eid、Did、working_time。

我写的代码是:

CREATE TRIGGER BUDGET_CHK
BEFORE
    INSERT OR UPDATE OF BUDGET OR DELETE ON DEPT
    FOR EACH ROW
    BEGIN
       UPDATE DEPT
       SET BUDGET = 
       (SELECT SUM(E.SALARY)
       FROM EMP E, WORKS W, DEPT D
       WHERE E.eid=W.eid AND D.did=W.did
       GROUP BY W.did)
    END;

我是甲骨文的新手。有人可以纠正我吗?谢谢!

错误(来自下面的 cmets):

pl/sql: sql statement ignored

ORA-00933 sql command not properly ended

Error(16): PLS-00103: Encountered the symbol "end-of-file" when expecting
  one of the following: ( begin case declare end exception exit for goto if
  loop mod null pragma raise return select update while with <an identifier>
  <a double-quoted delimited-identifier> <a bind variable> << continue close
  current delete fetch lock insert open rollback savepoint set sql execute
  commit forall merge pipe purge

【问题讨论】:

  • 现有的有什么问题?
  • 编译器以错误响应我
  • 'pl/sql: sql 语句被忽略''ORA-00933 sql 命令未正确结束。'
  • 'Error(16): PLS-00103: 在预期以下情况之一时遇到符号“文件结尾”:( begin case declare end exception exit for goto if loop mod null pragma raise return select update while with

标签: sql oracle plsql


【解决方案1】:
    CREATE OR REPLACE TRIGGER dept_trigger before

  INSERT OR UPDATE OF budget ON dept 

  FOR EACH row 

  declare

  l_budget NUMBER;

  BEGIN

    SELECT SUM(sal) INTO l_budget

    FROM employees e

    INNER JOIN works w

    ON w.eid       =e.eid;

    IF :new.budget < l_budget THEN

      raise_application_error(-20001,'Out of budget');

    END IF;

  END;

根据您的描述,它可能有效。

【讨论】:

    【解决方案2】:

    你在一个地方有几个问题。

    1. 你错过了“;” UPDATE 语句后的符号 - 这是技术错误。

    2. 您的 UPDATE 语句更改了 DEPT 表中的所有行 - 我认为这不是您所期望的。

    3. 您的子查询可以返回多于 1 行 - 这意味着您将收到“ORA-01427:单行子查询返回多于一行”运行时错误 可能你想要这样的东西:

       UPDATE DEPT D  
       SET BUDGET =   
           (SELECT SUM(E.SALARY)  
            FROM EMP E, WORKS W  
            WHERE E.eid=W.eid   
            AND D.did=W.did)  
       WHERE EXISTS (SELECT *  
                     FROM EMP E, WORKS W  
                     WHERE E.eid=W.eid   
                     AND D.did=W.did  
       );
      
    4. 您在 DEP 表上创建行级触发器并尝试在主体内更改 DEPT 表 - 您应该了解“变异表问题”:http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936

    5. 在多用户环境中,当多个事务可以更改表中的数据时 由于事务隔离,您的代码将得到不相关的结果。请学习 Oracle 概念:http://docs.oracle.com/cd/B28359_01/server.111/b28318/consist.htm

    【讨论】:

    • 你的观点很好,但这显然是一个家庭作业,所以关于在现实世界中编程的建议是无关紧要的。
    猜你喜欢
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多