javaee论坛

普通会员

225648

帖子

337

回复

351

积分

楼主
发表于 2017-08-27 17:26:05 | 查看: 1036 | 回复: 2
源库(ENV库)中定义如下包:

包定义如下:

CREATE OR REPLACE PACKAGE PKG_DATA_REPORT IS  -- Author  : JOHNFNASH  -- Created : 2017/6/8 17:48:03  -- Purpose : DATA REPORT TO YW  --数据同步存储过程  PROCEDURE SP_DATA_RESPORT;  --数据增量同步存储过程  PROCEDURE SP_DATA_INCREMENTAL_REPORT;END PKG_DATA_REPORT;

包具体实现如下:

CREATE OR REPLACE PACKAGE BODY PKG_DATA_REPORT IS  --数据同步存储过程   PROCEDURE SP_DATA_RESPORT IS      NODE_NAME    VARCHAR(40) := 'BASIC_DATA_SYNC';    V_START_TIME DATE;    V_END_TIME   DATE := SYSDATE;    DATA_ROW     T_DATA_SYNC_RECORD%ROWTYPE;    V_ERRORTEXT  VARCHAR(200);    BEGIN    --锁住记录防止并发上报    SELECT *      INTO DATA_ROW      FROM T_DATA_SYNC_RECORD R     WHERE R.DATA_SYNC_NAME = NODE_NAME       AND R.NUM = 1       FOR UPDATE;      IF DATA_ROW.RESULT IS NULL THEN      --如果上一次数据同步成功,则开始本次数据同步      V_START_TIME := DATA_ROW.END_TIME;    ELSE      --如果上一次数据同步失败,则继续上一次数据同步      V_START_TIME := DATA_ROW.START_TIME;      V_END_TIME   := DATA_ROW.END_TIME;    END IF;      ------------------- 部门数据同步 -------------------    --删除之前的记录    PROC_TRUNCATE_REMOTE_TAB@DBL_YW('T_DEPARTMENT');    --DELETE FROM T_DEPARTMENT@DBL_YW;    --重新写入记录      INSERT INTO T_DEPARTMENT@DBL_YW      SELECT D.ID,             D.NAMECN,             D.NAMEEN,             D.CODE,             D.PARENTID,             D.NAMENPATH,             D.NAMCNPATH        FROM T_DEPARTMENT D;   ------------------- 设备数据同步 -------------------      --写入记录      MERGE INTO T_DEVICE@DBL_LCMYW T1    USING (SELECT * FROM T_DEVICE) T2    ON ( T1.ID=T2.ID)    WHEN MATCHED THEN        UPDATE SET T1.STATUS = T2.STATUS, T1.TIMESTAMEP=T2.TIMESTAMEP    WHEN NOT MATCHED THEN         INSERT (ID, NAME, LABID, REGION, STATUS, CREATETIME, TIMESTAMEP, CREATOR)      VALUES(T2.ID,T2.NAME,T2.LABID,T2.REGION,T2.STATUS,T2.CREATETIME,T2.TIMESTAMEP,T2.CREATOR);      --写入本次数据同步结果    INSERT INTO T_DATA_SYNC_RECORD    VALUES      (NODE_NAME, SYSDATE, V_START_TIME, V_END_TIME, NULL, 0);    --执行序号加1      UPDATE T_DATA_SYNC_RECORD       SET NUM = NUM + 1     WHERE DATA_SYNC_NAME = NODE_NAME;      COMMIT;    EXCEPTION    WHEN OTHERS THEN      ROLLBACK; --事物回滚          V_ERRORTEXT := SUBSTR(SQLERRM, 1, 200); --错误信息      --写入本次数据同步结果      INSERT INTO T_DATA_SYNC_RECORD      VALUES        (NODE_NAME, SYSDATE, V_START_TIME, V_END_TIME, V_ERRORTEXT, 0);      --执行序号加1       UPDATE T_DATA_SYNC_RECORD         SET NUM = NUM + 1       WHERE DATA_SYNC_NAME = NODE_NAME;          COMMIT;  END; END SP_ENV_OPY_REPORT;END PKG_DATA_REPORT

其中涉及到的目标库(YW库) truncate表的存储过程 PROC_TRUNCATE_REMOTE_TAB@DBL_YW 定义如下:

CREATE OR REPLACE PROCEDURE PROC_TRUNCATE_REMOTE_TAB(P_TNAME IN VARCHAR2) ASBEGINEXECUTE IMMEDIATE 'TRUNCATE TABLE ' || P_TNAME;EXCEPTIONWHEN OTHERS THENRAISE_APPLICATION_ERROR(-20001, SQLERRM);END PROC_TRUNCATE_REMOTE_TAB;

由于表中数据量较大时,使用delete删除数据比较慢,使用truncate操作更快,但是oracle不允许执行远程库

的truncate。换个方式,在远程库建立存储过程,执行对该库中数据表的truncate操作,其它库建立dblink之后

,可以调用该存储过程,实现对远程库表的truncate操作。


下面对上面的比较关键的地方进行说明:
1) T_DATA_SYSNC_RECORD

刚进入存储过程时,锁住该表的记录,防止并发上报;然后根据上一次的执行结果确定本次执行的起始时间

、结束时间,特别是对于增量同步,每次只将时间段内的数据同步到目标库

(详见SP_DATA_INCREMENTAL_REPORT存储过程)

表的定义如下:
-- Create tablecreate table T_DATA_SYNC_RECORD(data_sync_name VARCHAR2(40) not null,timestamp DATE,start_time DATE,end_time DATE,result VARCHAR2(200),num NUMBER);-- Add comments to the columnscomment on column T_DATA_SYNC_RECORD.data_sync_nameis '数据同步任务名称';comment on column T_DATA_SYNC_RECORD.timestampis '任务执行时间';comment on column T_DATA_SYNC_RECORD.start_timeis '数据同步开始时间';comment on column T_DATA_SYNC_RECORD.end_timeis '数据同步结束时间';comment on column T_DATA_SYNC_RECORD.resultis '数据同步执行结果,为空表示成功';comment on column T_DATA_SYNC_RECORD.numis '序号,从1开始,每执行一次之前同一同步任务的序号加1';
2) 源库中需建立与目标库的dblink
 Create database link create database link DBL_YW connect to YWidentified by passwordusing 'ILCM';
3) 数据同步的形式

根据业务的不同,同步的方式可能有好几种,如删除目标库之前所有数据,重新写入(如果只是少量字段

的值可能有修改,可以使用merge into进行数据同步,如上);增量同步,每次只同步新增的记录到目标库

(适用于历史数据只读的情况)

4) 当有多个库的数据要汇总到同一个目标库时,可以在数据库添加一个表示来源于哪个节点的字段,每个库

的同步存储过程为这个字段设置不同的值,就可以区分数据是来源于哪个数据库。不过这种情况下,直接对

目标库进行truncate操作就不合适了,因为可能会导致数据丢失。这种情况怎么处理,这里就不叙述了。


本文远程库truncate实现参考:http://www.cnblogs.com/songdavid/articles/2153228.html


普通会员

0

帖子

313

回复

321

积分
沙发
发表于 2019-11-16 16:17:50

爱你呦

普通会员

0

帖子

315

回复

319

积分
板凳
发表于 2019-11-17 01:22:44

标记一下

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017