数据库SDB数据缓冲层(TBL数据缓冲层)向ODB数据贴源层(QSL近源模型层)拉链算法脚本【SQL部分】

一、数据准备

1:数据缓冲层(流水表)建表TBL:S01_LSB.SQL

CREATE TABLE S01_LSB (
  ACTNO NUMBER(4)  PRIMARY KEY
  ,OPNAME VARCHAR(10) 
  ,PASSWD VARCHAR(6)  
  ,CASH NUMBER(10,2)  
  ,OPDATE DATE  
  ,OPADDR VARCHAR(30)  
)
;
-- Add comments to the table 
comment on table S01_LSB
is '业务帐号流水表';
-- Add comments to the columns 
comment on column S01_LSB.ACTNO
  is '帐号';
comment on column S01_LSB.OPNAME
  is '开户人姓名';
comment on column S01_LSB.PASSWD
  is '密码';  
comment on column S01_LSB.CASH
  is '余额';  
comment on column S01_LSB.OPDATE
  is '开户日期';  
comment on COLUMN S01_LSB.OPADDR
  is '开户地址';  

二:数据贴源层(拉链表)建表QSL:S01_LLB.SQL

CREATE TABLE S01_LLB (
  ACTNO NUMBER(4)  PRIMARY KEY
  ,OPNAME VARCHAR(10) 
  ,PASSWD VARCHAR(6)  
  ,CASH NUMBER(10,2)  
  ,OPDATE DATE  
  ,OPADDR VARCHAR(30)
  ,ETL_START_DATE DATE
  ,ETL_END_DATE DATE
)
;
-- Add comments to the table 
comment on table S01_LSB
is '业务帐号流水表';
-- Add comments to the columns 
comment on column S01_LSB.ACTNO
  is '帐号';
comment on column S01_LSB.OPNAME
  is '开户人姓名';
comment on column S01_LSB.PASSWD
  is '密码';  
comment on column S01_LSB.CASH
  is '余额';  
comment on column S01_LSB.OPDATE
  is '开户日期';  
comment on COLUMN S01_LSB.OPADDR
  is '开户地址';  

二、拉链脚本

一:环境变量、子程序

二:流水表拉链SQL部分

–此脚本算法是从技术缓冲层(SDB)向近源模型层(ODB)加载状态类有删除表的带删除拉链算法(FULL JOIN方式)

–Step0:按照目标表相同的结构创建临时表,用于存放今天发生了增、改、删的,需要处理的数据;

DROP TABLE scott.T_S01_LLB;
commit;

WHENEVER SQLERROR EXIT SQL.SQLCODE;
CREATE TABLE scott.T_S01_LLB AS  
SELECT T.*,' 'as DEL_IND FROM scott.S01_LLB T
WHERE  1=2;
commit;

WHENEVER SQLERROR EXIT SQL.SQLCODE;
DELETE FROM  SCOTT.S01_LLB WHERE ETL_START_DATE >= SYSDATE;
commit;

WHENEVER SQLERROR EXIT SQL.SQLCODE;        
UPDATE  scott.S01_LLB SET ETL_END_DATE =  DATE '3000-12-31'
WHERE ETL_END_DATE >=SYSDATE;
commit;

删除旧临时表,同时删除ETL开始日期大于等于今天,修改ETL结束日期为今天的记录。
这一步的目的是为了支持重跑,当脚本报错或者需要修改时,删除今天拉链加载进模型层的数据,可以重新执行拉链脚本加载数据。
ETL_START_DATE与ETL_END_DATE可以按天结算(MM-DD-YYYY),这里偷懒直接读取系统时间,每次执行脚本都会根据系统时间判断新增数据;

–Step1:找出今天发生了增、删、改的记录,存入临时表;

INSERT /*+ append */ INTO scott.T_S01_LLB (
     ACTNO 
	,OPNAME
	,PASSWD 
	,CASH 
	,OPDATE 
	,OPADDR 
    ,ETL_START_DATE
    ,ETL_END_DATE
	,DEL_IND)
SELECT
         N.ACTNO
            , N.OPNAME
            , N.PASSWD
            , N.CASH
            , N.OPDATE
            , N.OPADDR                     
        , SYSDATE
    , DATE '3000-12-31'
    , CASE WHEN ( N.ACTNO IS NULL ) THEN 'D' ELSE 'N' END
FROM 
 (SELECT
    ACTNO
	,OPNAME
	,PASSWD
	,CASH
	,OPDATE
	,OPADDR
 FROM SCOTT.S01_LSB ) N
FULL JOIN
 (SELECT 
     ACTNO
	,OPNAME
	,PASSWD
	,CASH
	,OPDATE
	,OPADDR
 FROM SCOTT.S01_LLB 
 WHERE ETL_END_DATE = DATE '3000-12-31' ) T
ON NVL(N.ACTNO,0)=NVL(T.ACTNO,0)
WHERE
( T.ACTNO IS NULL ) OR ( N.ACTNO IS NULL ) OR (
 NVL(N.OPNAME,0) <> NVL(T.OPNAME,0) 
OR NVL(N.PASSWD,0) <> NVL(T.PASSWD,0) 
OR NVL(N.CASH,0) <> NVL(T.CASH,0) 
OR NVL(TO_CHAR(N.OPDATE),0) <> NVL(TO_CHAR(T.OPDATE),0) 
OR NVL(N.OPADDR,0) <> NVL(T.OPADDR,0) 
);
commit;

将T_S01_LLB中插入数据,内容为:S01_LSB与S01_LLB的全链接,连接条件是帐号相同,筛选出所有帐号相同,其他内容不同的记录、流水表有而拉链表没有的记录(标记DEL_IND为“N”,代表新增记录)、拉链表有而流水表没有的记录(标记DEL_IND为“D”,代表不需要从流水表拉链进入贴源层的记录)

–Step2:修改拉链表(将新变更的记录在拉链表中闭链)

merge into (SELECT * FROM SCOTT.S01_LLB WHERE ETL_END_DATE= DATE '3000-12-31') T
      using SCOTT.T_S01_LLB N on  ( NVL(N.ACTNO,0)=NVL(T.ACTNO,0) )
      when MATCHED then 
      update set    ETL_END_DATE=SYSDATE
;
commit;

用T_S01_LLB与S01_LLB进行merge更新,将上一部插入临时表所有新变更记录、与拉链表帐号相同的旧记录merge into比对,对匹配到的正式拉链表中的记录ETL_END_DATE时间从无穷大闭链为当前时间。

–Step3:插入新增、修改和删除的记录;

INSERT INTO SCOTT.S01_LLB 
SELECT
     ACTNO 
	,OPNAME
	,PASSWD 
	,CASH 
	,OPDATE 
	,OPADDR 
    ,ETL_START_DATE
    ,ETL_END_DATE 
FROM SCOTT.T_S01_LLB
WHERE DEL_IND='N';
COMMIT;

这里DEL_IND为“N”的记录包括两部分:
①:拉链表中无,流水表中有的记录;
②:拉链表与流水表匹配到且满足where条件内容变更的记录
拉链到此已完成从流水表更新到了拉链表。

三、测试

数据库SDB数据缓冲层(TBL数据缓冲层)向ODB数据贴源层(QSL近源模型层)拉链算法脚本【SQL部分】_第1张图片
在这里看到是当前的流水表;
数据库SDB数据缓冲层(TBL数据缓冲层)向ODB数据贴源层(QSL近源模型层)拉链算法脚本【SQL部分】_第2张图片
这是拉链表,可以看到曾经的闭链时间,闭链后新增的数据。

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