2014-02-09 31 views
0

我试着做到以下几点:PL/SQL触发器来概括行和更新其他行

写触发这样一个部门的预算在部门支付给员工的工资总和(记员工只在部门工作的时间百分比)。所述DEPT表包括部门ID(DID),预算,经理ID,所述员工(EMP)表包括EMPID(EID),工资,奖金,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; 

我是新来的Oracle。有人能纠正我吗?谢谢!

错误(从下面的评论):

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 
+0

现有的问题是什么? –

+0

编译器回应了我的错误 – jasonwzm

+0

发布错误 –

回答

0

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

  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

+0

您说得很好,但这显然是一项家庭作业,所以关于现实世界中编程的建议是无关紧要的。 – APC

0
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; 

从你的描述它可能工作。