当在同一个表中发生一个值的更改时,更新表中的整个列

时间:2014-03-17 11:20:30

标签: sql database oracle

我是PL / SQL编程的新手,我遇到了解决这个问题的问题:

问题陈述:

→EMPLOYEE_PAY表包含列(ID,NAME,LOCATION,BASIC_SALARY,NET_SALARY)。

公司对所有员工都有相同基本工资的政策,但净工资根据员工的表现而变化。因此,Basic Salary列必须始终具有相同的值。要求是

  1. 如果通过插入或更新更改了员工的基本工资,则 基本工资栏应以新值为主要值 并且该栏目将使用最新的基本工资进行更新。
  2. 更新基本工资栏时,净工资的值 对于每个员工也应该在主要方面进行相应的更新 表
  3. 净工资可以更新为 -

    新净工资=新基本工资*(旧净工资/旧基本工资)

    例: EMPLOYEE TABLE ID NAME LOCATION BASIC_SALARY NET_SALARY _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ 12102 John Bangalore 10000 25450 12155 Rana Hyderabad 10000 24500 12154 Kejriwal New Delhi 10000 25500 12553 Narendra Patna 10000 25250

    假设,如果将一个值插入此表或使用基本工资更新为12000,则该表应如下所示更新基本工资和净工资:

    EMPLOYEE TABLE ID NAME LOCATION BASIC_SALARY NET_SALARY _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ _ 12102 John Bangalore 12000 30540 12155 Rana Hyderabad 12000 29400 12154 Kejriwal New Delhi 12000 30600 12553 Narendra Patna 12000 30300 12455 Sachin Mumbai 12000 30500

    注意:需要使用PL / SQL中的触发器在Oracle DB上执行整个过程。

    我面临的主要问题是如何在处理一条记录时使用触发器更改以前的记录值?' - 因为'触发器一次处理一行' (根据我迄今为止关于触发器的知识)

    到目前为止,我已经厌倦了执行此操作的代码如下。

    CREATE TABLE EMPLOYEE_PAY(
      ID INT NOT NULL,
      NAME VARCHAR(20),
      LOCATION CHAR(25),
      BASIC_SALARY DECIMAL(18,2),
      NET_SALARY DECIMAL(18,2),
      PRIMARY KEY(ID)
    );
    
    
    CREATE OR REPLACE TRIGGER EMPLOYEE_BASIC_PAY
    BEFORE INSERT ON EMPLOYEE_PAY
    FOR EACH ROW
    BEGIN
      UPDATE EMPLOYEE_PAY
      SET BASIC_SALARY = :NEW.BASIC_SALARY
      WHERE BASIC_SALARY != :NEW.BASIC_SALARY;
    EXCEPTION
      WHEN OTHERS THEN NULL;
    END;
    
    
    CREATE OR REPLACE TRIGGER EMPLOYEE_NET_PAY
    BEFORE UPDATE OF BASIC_SALARY ON EMPLOYEE_PAY
    FOR EACH ROW
    BEGIN
      UPDATE EMPLOYEE_PAY
      SET NET_SALARY = :NEW.BASIC_SALARY * (:OLD.NET_SALARY/:OLD.BASIC_SALARY)
      WHERE BASIC_SALARY != :NEW.BASIC_SALARY;
    EXCEPTION
      WHEN OTHERS THEN NULL;
    END;
    

    当我尝试这个时,在结果集中,基本工资仅针对INSERT INTO更新,并且净工资保持不变。请尽快帮我解决可能的解决方案。

    谢谢

1 个答案:

答案 0 :(得分:1)

首先:您的数据模型并不好,因为您当然会注意到自己。如果所有员工的基本工资相同,为什么每个员工多余存储?如果净工资是基本工资乘以一个因素,为什么存储结果而不是因子?如果您刚刚更改了数据模型,那么根本就没有问题。

如果你必须坚持你的模特,这是我对你的触发器的评论:

  1. 在插入触发器中,您只更新basic_salary,在更新触发器中,您只更新net_salary。这不是你想要的。您想要更新两个触发器中的两个字段。 (你可以把这个组合插入/更新触发器)。
  2. :OLD值适用于正在插入或更新的记录。但是你应该使用你正在计算的记录的值。
  3. 在插入或更新后应用更改,因为您不想更改正在插入或更新的记录,而是更改所有记录。
  4.     CREATE OR REPLACE TRIGGER EMPLOYEE_PAY_CORRECTION
        AFTER INSERT OR UPDATE OF BASIC_SALARY ON EMPLOYEE_PAY
        FOR EACH ROW
        BEGIN
          UPDATE EMPLOYEE_PAY
          SET
            BASIC_SALARY = :NEW.BASIC_SALARY,
            NET_SALARY = NET_SALARY * :NEW.BASIC_SALARY / BASIC_SALARY
          WHERE BASIC_SALARY != :NEW.BASIC_SALARY;
        EXCEPTION
          WHEN OTHERS THEN NULL;
        END;
    
相关问题