用merge实现仓库数据的增量更新

本文只是用merge语句来实现仓库数据的增量更新,与以往使用的update、delete、insert并没有本质不同;之所以单独记录在这里,就是为了备查。
本文中使用的测试数据及其表结构,参见《仓库数据增量更新加载算法(支持混乱日期跑批) ,原文地址:http://blog.csdn.net/nsj820/article/details/6082478》博文;此文中数据重跑必须从需要重跑的那一天跑到当前日期;相应的测试代码都在存储过程脚本的下方,可供参考使用。

CREATE OR REPLACE PROCEDURE P_T100_BAL_IU_USE_MERGE
 (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_USE_MERGE';
 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;
      --增量更新历史回滚
      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 := 'MERGE INTO EDW_T100_BAL_IU 进行增量更新操作';
      MERGE INTO EDW_T100_BAL_IU T
      USING ODS_CMIS_YE O
      ON (T.ID = O.ID)
      WHEN MATCHED THEN
        UPDATE
           SET T.BAL = O.BAL, T.UPDATE_DT = ODS_DATA_DATE
         WHERE ODS_DATA_DATE = P_ETLDATE
      WHEN NOT MATCHED THEN
        INSERT
          (T.ID, T.BAL, T.UPDATE_DT)
        VALUES
          (O.ID, O.BAL, O.ODS_DATA_DATE) WHERE ODS_DATA_DATE = P_ETLDATE;

      --正常处理
      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 THEN
      BEGIN
             ROLLBACK;
             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;

--测试用代码
/*DECLARE
  O_RUNSTATUS NUMBER; --执行结果
  O_MSG       VARCHAR2(100);
BEGIN
  FOR V_KEY IN 20101201 .. 20101205 LOOP
    P_T100_BAL_IU_USE_MERGE(V_KEY, O_RUNSTATUS, O_MSG);
  END LOOP;
END;

--TRUNCATE TABLE EDW_T100_BAL_IU;
SELECT * FROM ODS_CMIS_YE ORDER BY 3, ROUND(ID);
SELECT * FROM EDW_T100_BAL_IU ORDER BY ROUND(ID), 3;

--数据验证
SELECT *
  FROM ODS_CMIS_YE
 WHERE (ID, ODS_DATA_DATE) IN
       (SELECT ID, MAX(ODS_DATA_DATE) FROM ODS_CMIS_YE GROUP BY ID)
 ORDER BY ROUND(ID);*/
/

 

你可能感兴趣的:(Oracle,Develop)