【问题标题】:Updating the entire column in table when change of one value occured in same table当同一个表中的一个值发生变化时更新表中的整个列
【发布时间】:2014-04-22 13:49:10
【问题描述】:

我对 PL/SQL 编程非常陌生,但在解决这个问题时遇到了问题:

问题陈述:

→ EMPLOYEE_PAY 表有列(ID、NAME、LOCATION、BASIC_SALARY、NET_SALARY)。

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

  1. 如果员工的基本工资被插入或更新更改,则 基本工资栏应假定新值为主值 并且该栏将更新为最新的基本工资。
  2. 当基本工资列更新时,净工资的值 对于每个员工也应该相应地更新在主要 表。

净工资可以更新为-

新净薪=新底薪*(旧净薪/旧底薪)

例如: 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

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

我面临的主要问题是“如何在处理一条记录时使用触发器更改以前的记录值?” - 因为“触发器一次只处理一行”(根据我目前对触发器的了解)

到目前为止,我已经厌倦了这样做的代码如下。

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,而净工资保持不变。请尽快帮我找出可能的解决方案。

谢谢

【问题讨论】:

  • 您的数据库模型存在根本缺陷。这不是你应该这样做的方式。

标签: sql database oracle


【解决方案1】:

首先:您的数据模型不好,您自己肯定注意到了。如果所有员工的基本工资都相同,为什么要为每个员工重复存储呢?如果净工资是基本工资乘以一个因子,为什么要存储结果而不是因子?如果您只是更改了数据模型,那么您将完全没有问题。

如果您必须继续使用您的模型,以下是我对您的触发器的评论:

  1. 在插入触发器中,您只更新 basic_salary,在更新触发器中,您只更新 net_salary。这不是你想要的。您想要更新两个触发器中的两个字段。 (不过,您可以制作一个组合的插入/更新触发器)。
  2. :OLD 值适用于正在插入或更新的记录。但您应该使用您正在计算的记录的值。
  3. 在插入或更新后应用更改,因为您不想更改正在插入或更新的记录,而是更改所有记录。
创建或替换触发器 EMPLOYEE_PAY_CORRECTION 在 EMPLOYEE_PAY 上插入或更新 BASIC_SALARY 之后 每一行 开始 更新 EMPLOYEE_PAY 放 BASIC_SALARY = :NEW.BASIC_SALARY, NET_SALARY = NET_SALARY * :NEW.BASIC_SALARY / BASIC_SALARY BASIC_SALARY != :NEW.BASIC_SALARY; 例外 当其他人为空时; 结尾;

【讨论】:

  • 我同意:该模型存在根本缺陷,应该重新设计,而不是通过触发器应用一些技巧来解决真正的问题。
猜你喜欢
  • 2018-04-21
  • 2011-02-10
  • 1970-01-01
  • 2023-03-17
  • 2021-01-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
相关资源
最近更新 更多