练习:-- 拉链表练习:
维度表源表
ID M_NAME REST UP_DATE
1 车贷 0.01 2022/12/1
2 房贷 0.03 2022/12/1
3 经营贷 0.015 2022/12/1
维度表拉链表
ID M_NAME REST BEGIN_DATE END_DATE
1 车贷 0.01 2022/12/1 4712/12/31
2 房贷 0.03 2022/12/1 4712/12/31
3 经营贷 0.015 2022/12/1 4712/12/31
---------------------------------------------------------
维度表源表
ID M_NAME REST UP_DATE
1 车贷 0.02 2023/1/1 --变化的数据
2 房贷 0.03 2022/12/1
3 经营贷 0.015 2022/12/1
4 彩礼贷 0.04 2023/1/1 --新增的数据
5 育儿贷 0.03 2023/1/1 --新增的数据
维度表拉链表
ID M_NAME REST BEGIN_DATE END_DATE
1 车贷 0.01 2022/12/1 2023/1/1 ---闭链 或 无效的
2 住房贷 0.03 2022/12/1 2023/1/1
3 经营贷 0.015 2022/12/1 4712/12/31
1 车贷 0.02 2023/1/1 4712/12/31 ---原记录的开链记录
4 彩礼贷 0.04 2023/1/1 4712/12/31 ---新增记录的开链记录
5 育儿贷 0.03 2023/1/1 4712/12/31 ---新增记录的开链记录
CREATE TABLE LOAN_PRODUCTS (ID NUMBER,M_NAME VARCHAR2(255),REST NUMBER(10,3),UP_DATE DATE);
INSERT INTO LOAN_PRODUCTS VALUES(1,'车贷',0.01,TO_DATE(20221201,'YYYYMMDD'));
INSERT INTO LOAN_PRODUCTS VALUES(2,'房贷',0.03,TO_DATE(20221201,'YYYYMMDD'));
INSERT INTO LOAN_PRODUCTS VALUES(3,'经营贷',0.015,TO_DATE(20221201,'YYYYMMDD'));
COMMIT;
SELECT * FROM LOAN_PRODUCTS;
-- 根据源表的数据建表,并添加拉链字段
CREATE TABLE LOAN_PRODUCTS_LALIAN
AS
SELECT T.ID,
T.M_NAME,
T.REST,
T.UP_DATE BEGIN_DATE,
TO_DATE(47121231,'YYYYMMDD') END_DATE
FROM LOAN_PRODUCTS T;
源表数据发生变化:
--新增两个贷款产品
INSERT INTO LOAN_PRODUCTS VALUES(4,'经营贷',0.04,TO_DATE(20230101,'YYYYMMDD'));
INSERT INTO LOAN_PRODUCTS VALUES(5,'育儿贷',0.03,TO_DATE(20230101,'YYYYMMDD'));
COMMIT;
--车贷利息发生变化
UPDATE LOAN_PRODUCTS SET REST=0.02,UP_DATE=TO_DATE(20230101,'YYYYMMDD') WHERE ID = 1;
UPDATE LOAN_PRODUCTS SET M_NAME='住房贷',UP_DATE=TO_DATE(20230101,'YYYYMMDD') WHERE ID = 2;
COMMIT;
-- 查询表中的数据
SELECT * FROM LOAN_PRODUCTS FOR UPDATE; ----源表
SELECT * FROM LOAN_PRODUCTS_LALIAN FOR UPDATE;----拉链表
加上FOR UPDATE可以在下面查询的结果,直接改数据
-- 拉链表业务的3个步骤:
1.先判断源表有没有数据发生变化,有发生变化的则插入新的开链记录.
2.把这次有发生变化的拉链表记录,做闭链
3.判断源表有没有新的记录,有则往拉链表增加新的开链记录.
CREATE OR REPLACE PROCEDURE SP_LALIAN_EXISTS
AS
-- 1. 将源表和目标表的数据进行比较,将修改的数据放入到游标中
CURSOR C_LOAN
IS
SELECT
L.ID,
L.M_NAME,
L.REST,
L.UP_DATE
FROM LOAN_PRODUCTS L
WHERE EXISTS(
SELECT 1
FROM LOAN_PRODUCTS_LALIAN T2
WHERE T2.ID=L.ID
AND (T2.M_NAME<>L.M_NAME OR T2.REST<>L.REST)
AND T2.END_DATE=TO_DATE('47121231','YYYYMMDD')
);
BEGIN
------------------------------------------------------------------------------
-- 1先判断 源表有没有发生变化,有发生变化,则插入新的开练记录
INSERT INTO LOAN_PRODUCTS_LALIAN
SELECT
T1.ID,
T1.M_NAME,
T1.REST,
T1.UP_DATE,
TO_DATE(47121231,'YYYYMMDD') -- 开链记录插入
FROM LOAN_PRODUCTS T1
WHERE EXISTS (
SELECT 1
FROM LOAN_PRODUCTS_LALIAN T2
WHERE T1.ID=T2.ID
AND (T1.M_NAME <> T2.M_NAME OR T1.REST <> T2.REST)
AND T2.END_DATE=TO_DATE(47121231,'YYYYMMDD')
);
-------------------------------------------------------------------------------------
-- 2把这次发生变化的拉链表记录,做闭链
FOR X IN C_LOAN LOOP
UPDATE LOAN_PRODUCTS_LALIAN SET END_DATE=X.UP_DATE
WHERE ID=X.ID AND (M_NAME <> X.M_NAME OR REST<>X.REST)
AND END_DATE=TO_DATE(47121231,'YYYYMMDD');
END LOOP;
-------------------------------------------------------------------------------------
-- 3.判断源表有没有新的记录,有则往拉链表增加新的开链记录
INSERT INTO LOAN_PRODUCTS_LALIAN
SELECT
T1.ID,
T1.M_NAME,
T1.REST,
T1.UP_DATE,
TO_DATE(47121231,'YYYYMMDD')
FROM LOAN_PRODUCTS T1
WHERE NOT EXISTS(
SELECT 1
FROM LOAN_PRODUCTS_LALIAN T2
WHERE T1.ID=T2.ID
);
END SP_LALIAN_EXISTS;
调用
BEGIN
SP_LALIAN_EXISTS();
END;
SELECT * FROM LOAN_PRODUCTS_LALIAN