【问题标题】:Updating serial no. in a table on events of data insert and data delete更新序列号在数据插入和数据删除事件表中
【发布时间】:2017-07-31 09:04:42
【问题描述】:

假设我有一个三列的表;序列号、员工姓名和员工薪水。每当将数据插入此表时,序列 ID 列都会增加值,如 1、2、3、4 等。现在下一部分是每当数据被删除时,整个 Serial Id 值都会得到调整。行的删除可以发生在起始行、最后一行或表中的任何位置。我们如何通过 PL/SQL 完成这项工作。

【问题讨论】:

  • 你所说的“整个序列号值都将得到调整”是什么意思?请用示例数据详细说明。
  • 我建议您添加一个额外的列,该列将具有从序列生成的真实 ID 值(这对于您可能在该列上具有的索引或 PK 约束有好处)。然后,无论是在表中插入记录的过程中,还是在触发器中(插入、更新、删除之前的触发器),您都可以按照您喜欢的方式调整任何列,然后 Oracle 将提交它(如果您有这个当然是在代码中)。
  • @KaushikNayak。“将调整整个序列号值”意味着假设表中有 10 行,序列号是从 1 到 10 创建的。现在如果最后一行被删除(其中是更容易的部分)序列号将从 1 到 9 存在。但是,如果第一行被删除,那么第二行的序列号 =1,第三行的序列号 = 2,依此类推。再次假设如果第 5 行被删除,那么前 4 行将保持不变,但第 6 行的 Serial Id = 5,第 7 行的 Serial Id = 6,依此类推。每当有删除时,此事件必须自动发生。

标签: sql oracle plsql oracle11g


【解决方案1】:

好的。这可以使用以下步骤来完成,但请注意,您不能直接从表中删除。相反,您可以从具有相同结构的视图中删除并使用替代触发器更新父表。此外,由于您要从员工表中删除 ID,因此应该至少有一个其他键来唯一标识员工。考虑到所有这些前体,以下是步骤。

创建一个UNIQUE KEY ON employee_name。如果您可以确保employee_name 在整个表中始终是唯一的,则此步骤不是强制性的。但如果我们不这样做,就无法识别员工记录。

ALTER TABLE emp ADD CONSTRAINT emp_uk UNIQUE(employee_name);

下一步创建一个与emp 表具有相同定义的视图。

CREATE OR REPLACE VIEW emp_view AS
SELECT * FROM EMP;

为逐行删除操作创建一个INSTEAD OF TRIGGER 在视图上emp_view

CREATE OR REPLACE TRIGGER trigg_emp_v INSTEAD OF
  DELETE ON emp_view FOR EACH ROW
BEGIN
  DELETE
  FROM EMP
  WHERE emp_id = :OLD.emp_id ;
  MERGE INTO EMP e USING
  (SELECT RANK() OVER (ORDER BY emp_id) emp_id,
    employee_name,
    salary
  FROM
    ( SELECT * FROM emp WHERE emp_id != :OLD.emp_id
    )
  ) v ON ( e.employee_name = v.employee_name )
WHEN MATCHED THEN
  UPDATE SET e.emp_id = v.emp_id;
END;
/

这里的选择查询正在使用RANK() 函数获取重新计算的emp_id,而merge 语句正在更新emp 表。

测试ID = 5

Before Deletion

    SELECT * FROM EMP;

    EMP_ID EMPLOYEE_NAME                                SALARY
---------- ---------------------------------------- ----------
         1 EMPLOYEE_1                                     1001
         2 EMPLOYEE_2                                     1002
         3 EMPLOYEE_3                                     1003
         4 EMPLOYEE_4                                     1004
         5 EMPLOYEE_5                                     1005
         6 EMPLOYEE_6                                     1006
         7 EMPLOYEE_7                                     1007
         8 EMPLOYEE_8                                     1008
         9 EMPLOYEE_9                                     1009
        10 EMPLOYEE_10                                    1010
--------------------------------------------------------------------

删除操作

DELETE FROM EMP_VIEW where emp_id = 5;

删除后,输出是这样的。

SELECT * FROM EMP;
    EMP_ID EMPLOYEE_NAME                                SALARY
---------- ---------------------------------------- ----------
         1 EMPLOYEE_1                                     1001
         2 EMPLOYEE_2                                     1002
         3 EMPLOYEE_3                                     1003
         4 EMPLOYEE_4                                     1004
         5 EMPLOYEE_6                                     1006
         6 EMPLOYEE_7                                     1007
         7 EMPLOYEE_8                                     1008
         8 EMPLOYEE_9                                     1009
         9 EMPLOYEE_10                                    1010

让我知道您的反馈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 2021-03-20
    相关资源
    最近更新 更多