仓库数据增量更新加载算法(支持混乱日期跑批)

1、  建库及测试数据插入脚本

--建增量更新目标表
-- Create table
create table EDW_T100_BAL_IU
( ID        VARCHAR2(8) not null,BAL       NUMBER(22,2),UPDATE_DT VARCHAR2(8)
);
-- Add comments to the table 
comment on table EDW_T100_BAL_IUis '余额(增量更新方式加载)表';
-- Add comments to the columns 
comment on column EDW_T100_BAL_IU.IDis '主键ID';
comment on column EDW_T100_BAL_IU.BALis '余额';
comment on column EDW_T100_BAL_IU.UPDATE_DTis '更新日期';
-- Create/Recreate primary, unique and foreign key constraints 
alter table EDW_T100_BAL_IUadd constraint EDW_T100_BAL_IU_ID primary key (ID);
--建增量更新用到的临时表
-- Create table
create global temporary table TMP_T100_BAL_IU
( ID        VARCHAR2(8) not null,BAL       NUMBER(22,2),UPDATE_DT VARCHAR2(8) not null
)
on commit delete rows;
-- Create/Recreate primary, unique and foreign key constraints 
alter table TMP_T100_BAL_IUadd constraint TMP_T100_BAL_IU_ID_UPDT primary key (ID, UPDATE_DT);
--建日志表
create table EDW_ETL_LOG_DETAIL
( PROC_NAME       VARCHAR2(50),P_ETLDATE       VARCHAR2(20),ETL_MEMO        VARCHAR2(10),ETL_RECORD_NUM  INTEGER,ERR_MSG         VARCHAR2(1000),ERR_SQL         VARCHAR2(1000),TABLE_NAME      VARCHAR2(50),START_TIMESTAMP TIMESTAMP(6),END_TIMESTAMP   TIMESTAMP(6)
);
--建源表及插入源测试数据
-- Create table
create table ODS_CMIS_YE
( ID            VARCHAR2(8) not null,BAL           NUMBER(22,2),ODS_DATA_DATE VARCHAR2(8) not null
);
-- Add comments to the table 
comment on table ODS_CMIS_YEis 'ODS余额表(提供的是增量更新数据)';
-- Add comments to the columns 
comment on column ODS_CMIS_YE.IDis '主键ID';
comment on column ODS_CMIS_YE.BALis '余额';
comment on column ODS_CMIS_YE.ODS_DATA_DATEis 'ODS数据日期';
-- Create/Recreate primary, unique and foreign key constraints 
alter table ODS_CMIS_YEadd constraint ODS_CMIS_YE primary key (ID, ODS_DATA_DATE);
--insert test data
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('4', 34545.09, '20101202');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('1', 10.10, '20101201');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('2', 20.30, '20101201');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('3', 22.10, '20101204');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('4', 33.80, '20101205');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('5', 66.09, '20101203');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('6', 8889.08, '20101204');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('7', 2324.07, '20101205');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('8', 232449.98, '20101201');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('9', 3434.99, '20101201');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('1', 23.99, '20101202');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('2', 20.30, '20101202');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('1', 3333.98, '20101203');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('10', 3453252.09, '20101203');
insert into ods_cmis_ye (ID, BAL, ODS_DATA_DATE) values ('11', 2343432.78, '20101202');
commit;

2、  增量更新示例代码

CREATE OR REPLACE PROCEDURE P_T100_BAL_IU(P_ETLDATE  IN    VARCHAR2,    --日期参数O_RUNSTATUS OUT   NUMBER,      --执行结果O_MSG       OUT   VARCHAR2     --错误返回) AS--Procedure Name:P_T100_BAL_IU
--Author        :nisj
--Script File   :P_T100_BAL_IU.SQL
/*###################################################*/
--Souce Databse.table  :
--ODS_CMIS_YE         ODS余额表(提供的是增量更新数据)
/*###################################################*/
--Target Databse.table :
--EDW_T100_BAL_IU     余额(增量更新方式加载)表
/*###################################################*/
--加载方式:增量更新--定义存储过程信息V_PROC_NAME       VARCHAR2(50)   := 'P_T100_BAL_IU';V_TABLE_NAME      VARCHAR2(50)   := 'EDW_T100_BAL_IU';V_START_TIMESTAMP TIMESTAMP;                --加载开始时间V_END_TIMESTAMP   TIMESTAMP;                --加载结束时间V_RECORD_NUMBER   INTEGER;                  --记录数--定义错误代码,错误状态V_SQLERRM         VARCHAR2(1000);           --异常信息V_ERR_SQL         VARCHAR2(1000);           --出错位置BEGIN--捕获过程开始时间SELECT SYSDATE INTO V_START_TIMESTAMP FROM DUAL;--增量更新P_ETLDATE后的数据处理--TMP_T100_BAL_IU存储的是EDW表中大于等于更新日期的所有临时数据,大于的由备份得到,等于的由加载当天数据时得到--大于跑批日期的的数据备份条件是Update_Dt > P_ETLDATE,而删除目标表时是Update_Dt >= P_ETLDATEV_ERR_SQL := 'INSERT INTO TMP_T100_BAL_IU FROM EDW_T100_BAL_IU WHERE Update_Dt > P_ETLDATE';INSERT INTO TMP_T100_BAL_IUSELECT * FROM EDW_T100_BAL_IU WHERE Update_Dt > P_ETLDATE;V_ERR_SQL := 'DELETE FROM EDW_T100_BAL_IU WHERE Update_Dt >= P_ETLDATE';DELETE FROM EDW_T100_BAL_IU WHERE Update_Dt >= P_ETLDATE;--加载当天全量数据V_ERR_SQL := 'INSERT INTO TMP_T100_BAL_IU  FROM ODS_CMIS_YE';INSERT INTO TMP_T100_BAL_IU--该表无主键,但逻辑主键是(ID、UPDATE_DT)的复合主键(ID                --主键ID,BAL               --余额,UPDATE_DT         --更新日期)SELECT  a1.ID              --主键ID,a1.BAL            --余额,a1.ODS_DATA_DATE  --ODS数据日期FROM    ODS_CMIS_YE        a1WHERE   Ods_Data_Date = P_ETLDATE;--增量更新操作--按主键删除更新部分记录V_ERR_SQL := 'DELETE FROM EDW_T100_BAL_IU WHERE (ID) IN TMP_T100_BAL_IU';DELETE FROM EDW_T100_BAL_IUWHERE   (ID)IN      (SELECT IDFROM TMP_T100_BAL_IU);--插入新增和更新数据V_ERR_SQL := 'INSERT INTO EDW_T100_BAL_IU WHERE TMP_T100_BAL_IU [ID,MAX(UPDATE_DT)]';INSERT INTO EDW_T100_BAL_IU(ID              --主键ID,BAL            --余额,UPDATE_DT      --更新日期)SELECT  ID              --主键ID,BAL            --余额,UPDATE_DT      --更新日期FROM    TMP_T100_BAL_IUWHERE   (ID,UPDATE_DT)IN      (SELECT ID,MAX(UPDATE_DT)FROM TMP_T100_BAL_IUGROUP BY ID);--正常处理V_RECORD_NUMBER := SQL%ROWCOUNT;SELECT SYSDATE INTO V_END_TIMESTAMP FROM dual;INSERT INTO EDW_ETL_LOG_DETAIL(START_TIMESTAMP,END_TIMESTAMP,PROC_NAME,TABLE_NAME,ETL_RECORD_NUM,ETL_MEMO,P_ETLDATE)VALUES (V_START_TIMESTAMP,V_END_TIMESTAMP,V_PROC_NAME,V_TABLE_NAME,V_RECORD_NUMBER,'成功',P_ETLDATE);COMMIT;--异常处理EXCEPTION WHEN OTHERS THENBEGINROLLBACK;V_SQLERRM := SQLERRM;INSERT INTO EDW_ETL_LOG_DETAIL(START_TIMESTAMP,END_TIMESTAMP,PROC_NAME,TABLE_NAME,ETL_RECORD_NUM,ETL_MEMO,ERR_MSG,ERR_SQL,P_ETLDATE)VALUES (V_START_TIMESTAMP,V_END_TIMESTAMP,V_PROC_NAME,V_TABLE_NAME,0,'失败',V_SQLERRM,V_ERR_SQL,P_ETLDATE);O_RUNSTATUS := 1;O_MSG := 'PROGRAMMING ERROR HAPPENED';COMMIT;END;END;
/

3、  结果测试

Incremental_Update
truncate table edw_t100_bal_iu;
select * from ods_cmis_ye;
select * from edw_t100_bal_iu;
--无论批如何调,只要保证每一天都调了,edw_t100_bal_iu就会和下面的SQL得出的结果一致!
SELECT *FROM ODS_CMIS_YEWHERE ODS_DATA_DATE <= '20101205'AND (ID, ODS_DATA_DATE) IN(SELECT ID, MAX(ODS_DATA_DATE) FROM ODS_CMIS_YE GROUP BY ID);p_t100_bal_iu;
p_t100_bal_iu_new;
select * from edw_etl_log_detail order by 8 desc;

4、  总结说明

此过程代码,对于如12.5号数据已经跑完但发现12.1号那天的源数据有问题的情况,我们只要重新调度12.1的批就可以了,而不必从12.1号一直跑到当天,且能保证数据的完整性;而对于如果发现某一天数据有问题,需要从出错那一天起一直跑到当天的情况,代码如下,可根据实际情况选用。

CREATE OR REPLACE PROCEDURE P_T100_BAL_IU(P_ETLDATE  IN    VARCHAR2,    --日期参数O_RUNSTATUS OUT   NUMBER,      --执行结果O_MSG       OUT   VARCHAR2     --错误返回) AS--Procedure Name:P_T100_BAL_IU
--Author        :nisj
--Script File   :P_T100_BAL_IU.SQL
/*###################################################*/
--Souce Databse.table  :
--ODS_CMIS_YE         ODS余额表(提供的是增量更新数据)
/*###################################################*/
--Target Databse.table :
--EDW_T100_BAL_IU     余额(增量更新方式加载)表
/*###################################################*/
--加载方式:增量更新--定义存储过程信息V_PROC_NAME       VARCHAR2(50)   := 'P_T100_BAL_IU';V_TABLE_NAME      VARCHAR2(50)   := 'EDW_T100_BAL_IU';V_START_TIMESTAMP TIMESTAMP;                --加载开始时间V_END_TIMESTAMP   TIMESTAMP;                --加载结束时间V_RECORD_NUMBER   INTEGER;                  --记录数--定义错误代码,错误状态V_SQLERRM         VARCHAR2(1000);           --异常信息V_ERR_SQL         VARCHAR2(1000);           --出错位置BEGIN--捕获过程开始时间SELECT SYSDATE INTO V_START_TIMESTAMP FROM DUAL;--增量更新历史回滚DELETE FROM EDW_T100_BAL_IU WHERE Update_Dt >= P_ETLDATE;--加载当天全量数据V_ERR_SQL := 'INSERT INTO TMP_T100_BAL_IU  FROM ODS_CMIS_YE';INSERT INTO TMP_T100_BAL_IU(ID             --主键ID,BAL            --余额,UPDATE_DT      --更新日期)SELECT  a1.ID              --主键ID,a1.BAL            --余额,a1.ODS_DATA_DATE  --ODS数据日期FROM    ODS_CMIS_YE        a1WHERE   Ods_Data_Date = P_ETLDATE;--增量更新操作--按主键删除更新部分记录DELETE FROM EDW_T100_BAL_IUWHERE   (ID)IN      (SELECT IDFROM    TMP_T100_BAL_IU);--出入新增和更新数据INSERT INTO EDW_T100_BAL_IU(ID              --主键ID,BAL            --余额,UPDATE_DT      --更新日期)SELECT  ID              --主键ID,BAL            --余额,UPDATE_DT      --更新日期FROM    TMP_T100_BAL_IU;--正常处理V_RECORD_NUMBER := SQL%ROWCOUNT;SELECT SYSDATE INTO V_END_TIMESTAMP FROM dual;INSERT INTO EDW_ETL_LOG_DETAIL(START_TIMESTAMP,END_TIMESTAMP,PROC_NAME,TABLE_NAME,ETL_RECORD_NUM,ETL_MEMO,P_ETLDATE)VALUES (V_START_TIMESTAMP,V_END_TIMESTAMP,V_PROC_NAME,V_TABLE_NAME,V_RECORD_NUMBER,'成功',P_ETLDATE);COMMIT;--异常处理EXCEPTION WHEN OTHERS THENBEGINROLLBACK;V_SQLERRM := SQLERRM;INSERT INTO EDW_ETL_LOG_DETAIL(START_TIMESTAMP,END_TIMESTAMP,PROC_NAME,TABLE_NAME,ETL_RECORD_NUM,ETL_MEMO,ERR_MSG,ERR_SQL,P_ETLDATE)VALUES (V_START_TIMESTAMP,V_END_TIMESTAMP,V_PROC_NAME,V_TABLE_NAME,0,'失败',V_SQLERRM,V_ERR_SQL,P_ETLDATE);O_RUNSTATUS := 1;O_MSG := 'PROGRAMMING ERROR HAPPENED';COMMIT;END;END;
/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/97789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023年湘潭大学OJ作业1 XTU OJ 1063,1064,1065,1066,1067 2023年下学期《C语言》作业0x00-输入输出

第一题 #include<stdio.h>int main() {int a;scanf("%d",&a);printf("%d,%X",a,a);return 0; } 十六进制使用%x来表示&#xff0c;注意x是大写就出输出的是大写字母&#xff0c;x是小写就输出的是小写字母 第二题 #include<stdio.h>in…

[C++基础]-多态

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。 本期学习目标&am…

数据库配置mysql5.7

1 创建数据库 """ 1.管理员连接数据库 mysql -uroot -proot2.创建数据库 create database hello default charsetutf8;3.查看用户 select user,host,password from mysql.user;# 5.7往后的版本 select user,host,authentication_string from mysql.user; "…

力扣-345.反转字符串中的元音字母

Idea 将s中的元音字母存在字符串sv中&#xff0c;并且使用一个数组依次存储元音字母的下标。 然后将字符串sv进行反转&#xff0c;并遍历元音下标数组&#xff0c;将反转后的字符串sv依次插入到源字符串s中 AC Code class Solution { public:string reverseVowels(string s) {…

【进阶C语言】数组笔试题解析

本节内容以刷题为主&#xff0c;大致目录&#xff1a; 1.一维数组 2.字符数组 3.二维数组 学完后&#xff0c;你将对数组有了更全面的认识 在刷关于数组的题目前&#xff0c;我们先认识一下数组名&#xff1a; 数组名的意义&#xff1a;表示数组首元素的地址 但是有两个例外…

强化学习环境 - robogym - 学习 - 3

强化学习环境 - robogym - 学习 - 3 文章目录 强化学习环境 - robogym - 学习 - 3项目地址为什么选择 robogymObservation - 观测信息Action - 动作信息Initialization - 初始状态设置 项目地址 https://github.com/openai/robogym 为什么选择 robogym 自己的项目需要做一些机…

软考 系统架构设计师系列知识点之软件架构风格(7)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之软件架构风格&#xff08;6&#xff09; 这个十一注定是一个不能放松、保持“紧”的十一。由于报名了全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff0c;11月4号就要考试&#xff0c;因此…

SQL创建与删除索引

索引创建、删除与使用&#xff1a; 1.1 create方式创建索引&#xff1a;CREATE [UNIQUE – 唯一索引 | FULLTEXT – 全文索引 ] INDEX index_name ON table_name – 不指定唯一或全文时默认普通索引 (column1[(length) [DESC|ASC]] [,column2,…]) – 可以对多列建立组合索引 …

【JS原型链,常见的修改原型对象的方法有哪些?】

原型链 什么是原型链修改原型对象的方法1. 修改原型对象上的属性和方法2. 重写原型对象3. 使用Object.create创建新的原型对象4. 使用Object.setPrototypeOf修改原型链 什么是原型链 JavaScript中每个对象都有一个内部属性[[Prototype]]指向它的原型对象&#xff0c;原型对象也…

acwing算法基础之基础算法--高精度乘法算法

目录 1 知识点2 模板 1 知识点 大数乘以小数 大数的每一位与小数相乘 2 模板 //A是大数&#xff0c;b是小数 //最后去除高位上的0 vector<int> mul(vector<int>& A, int b) {vector<int> C;int t 0;for (int i 0; i < A.size() || t; i) {if (i …

8.2 JUC - 7.线程安全集合类概述

目录 一、遗留的线程安全集合二、使用 Collections 装饰的线程安全集合三、java.util.concurrent.* 包下的对象 线程安全集合类可以分为三大类&#xff1a; 一、遗留的线程安全集合 Hashtable &#xff0c; Vector 二、使用 Collections 装饰的线程安全集合 Collections.sy…

salesforce点击classic按钮调用lightning组件

创建按钮&#xff0c;选择visualforce 页面&#xff0c;然后创建visualforce页面。 how to Call a Lightning component from a Classic custom button You can definitely call a Lightning Component from a Classic custom button. However, the process is not straightfo…

微信小程序使用路由传参和传对象的方法

近期在做微信小程序开发&#xff0c;在页面跳转时&#xff0c;需要携带参数到下一个页面&#xff0c;尤其是将对象传入页面。为了方便重温&#xff0c;特此记录。 路由传字符串参数 原始页面 传递字符串参数比较简单。路由跳转有两种方式&#xff0c;一种是通过navigator组件…

企业AI工程化之路:如何实现高效、低成本、高质量的落地?

MLOps工程实践 概述面临挑战目的内容简介读者对象专家推荐目录 写在末尾&#xff1a; 主页传送门&#xff1a;&#x1f4c0; 传送 概述 作为计算机科学的一个重要领域&#xff0c;机器学习也是目前人工智能领域非常活跃的分支之一。机器学习通过分析海量数据、总结规律&#x…

Java异常:基本概念、分类和处理

Java异常&#xff1a;基本概念、分类和处理 在Java编程中&#xff0c;异常处理是一个非常重要的部分。了解如何识别、处理和避免异常对于编写健壮、可维护的代码至关重要。本文将介绍Java异常的基本概念、分类和处理方法&#xff0c;并通过简单的代码示例进行说明。 一、什么…

Flask实现注册登录模块

&#x1f64c;秋名山码民的主页 &#x1f602;oi退役选手&#xff0c;Java、大数据、单片机、IoT均有所涉猎&#xff0c;热爱技术&#xff0c;技术无罪 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 获取源码&#xff0c;添加WX 目录 前言1.…

AIGC(生成式AI)试用 8 -- 曾经的难题

长假&#xff0c;远离电脑、远离手机、远离社交。 阴雨连绵&#xff0c;望着窗外发呆&#xff0c;AIGC为何物&#xff1f;有什么问题要问AIGC&#xff1f;AIGC可以代替我来发呆&#xff0c;还是可是为我空出时间发呆&#xff1f; 如果可以替代我发呆&#xff0c;要我何…

机器学习之SGD, Batch, and Mini Batch的简单介绍

文章目录 总述SGD(Stochastic Gradient Descent)(随机梯度下降&#xff09;Batch &#xff08;批量&#xff09;mini Batch (迷你批量&#xff09; 总述 SGD, Batch, and Mini Batch是可用于神经网络的监督学习计算权重更新的方案&#xff0c;即∆wij。 SGD(Stochastic Gradi…

el-tree中插入图标并且带提示信息

<template><div class"left"><!-- default-expanded-keys 默认展开 --><!-- expand-on-click-node 只有点击箭头才会展开树 --><el-tree :data"list" :props"defaultProps" node-click"handleNodeClick" :…

c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))

上篇文章介绍了一些常用的字符串函数&#xff0c;大家可以跳转过去浏览一下&#xff1a;c语言进阶部分详解&#xff08;详细解析字符串常用函数&#xff0c;并进行模拟实现&#xff08;上&#xff09;&#xff09;_总之就是非常唔姆的博客-CSDN博客 今天接着来介绍一些&#x…