我想捕获员工部门的变化并使用 scd 的 plsql 实现更新工资。请提出解决方案
仅尝试了 scd1 但希望保留部门的历史记录 如果部门变动应该有新的记录。如果工资变动的话要实施哪个scd
不要使用术语 SCD(缓慢变化维度),因为它不是一个普遍理解的术语,也不是很准确。 SCD 或 CDC 逻辑有多种类型。您可能正在考虑数据仓库中常见的 2 类表,该表历史上对行进行版本控制。即使这样,2 类表也有许多变体。它们是否有当前标志、如何表示未过期行的结束日期、结束日期是否等于下一行的开始日期或晚于其 1 秒或 1 天、如何表示逻辑删除等。 .
您可以通过一次合并来最佳地进行类型 2 维护,该合并将旧行的过期和新行的创建结合在一个操作中(逻辑删除需要第二次合并)。但这有点先进了。对于较小的容量来说,更适合开始的更简单的方法是逐行 PL/SQL。
采用最简单的情况并将其过度简化(这不处理删除或可为空的列等,以及您需要考虑的一些其他细节,但它为您提供了总体思路):
BEGIN
FOR rec_data IN (SELECT n.pkcol,
n.col1 new$col1,
n.col2 new$col2,
n.col3 new$col3,
o.col1 old$col1,
o.col2 old$col2,
o.col3 old$col3,
o.ROWID row_id
FROM newdata n,
olddata o
WHERE n.keycol = o.keycol(+)) -- outer join old and new together
LOOP
IF rec_data.row_id IS NULL
THEN
-- the row is new. insert an unexpired row
INSERT INTO olddata (pkcol,col1,col2,col3,startdate,enddate)
VALUES (rec_data.pkcol,rec_data.new$col1,rec_data.new$col2,rec_data.new$col3,SYSDATE,NULL);
-- test for column changes. Any nullable cols should be wrapped in NVL
ELSIF NOT (rec_data.new$col1 = rec_data.old$col1 AND
rec_data.new$col2 = rec_data.old$col2 AND
rec_data.new$col3 = rec_data.old$col3)
THEN
-- the row is old but has changed. expire the old row by setting its end date and insert a new unexpired row
UPDATE olddata
SET enddate = SYSDATE
WHERE ROWID = rec_data.row_id;
INSERT INTO olddata (pkcol,col1,col2,col3,startdate,enddate)
VALUES (rec_data.pkcol,rec_data.new$col1,rec_data.new$col2,rec_data.new$col3,SYSDATE,NULL);
END IF;
END LOOP;
END;