PL/SQL拉链表

练习:-- 拉链表练习:
维度表源表
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可以在下面查询的结果,直接改数据 

PL/SQL拉链表_第1张图片

-- 拉链表业务的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

你可能感兴趣的:(PL/SQL,sql,数据库)