ODI中删除数据的处理
ODI中删除数据的处理
一、前提知识:
数据从源数据库向数据仓库抽取时,一般采用以下几种方式:
- 全抽取模式
如果表的数据量较小,则可以采取全表抽取方式,以TRUNCATE/INSERT方式进行数据抽取。 - 基于时间戳的抽取模式
如果源数据表是不可更新的数据(如大多数事务处理数据)或者是不可删除数据(只能失效历史记录的情况),则根据变更时间戳,抽取最新变更的数据进行同步。 - 日志分析
如果没有更新时间戳,或者源数据存在删除的情况,则可以进行日志分析,来执行最新数据变更的同步。
说明:时间戳的方式如果要处理删除数据的情况,需要在源表创建触发器来捕获删除的记录。
ODI在数据抽取方面,添加了CDC(Changed Data Capture)的功能,并且包含两种方式,一种是在源数据库表上增加触发器来捕获新增、修改和删除的数据到日志表中。另一种是通过对日志的挖掘(Oracle的Log Miner和IBM DB2/400)。但是ODI的CDC,必须要求源表有主键。
二、删除数据的问题引入
当我们开始使用ODI来进行CDC方式的数据同步时,一切都正常,删除的数据也可以正确的同步到目标数据库。接着,因为业务需求,我们只需要同步部分数据到目标数据库,也就是为源数据表加上过滤,这样问题就出来了,新增和修改的数据都能正确的同步到目标数据库,而源数据表删除的数据,经过ODI Interface执行之后,目标数据表中还存在。
经过检查,Interface在装载数据时查询日志视图,而日志视图是日志表与源表的外连接,其结果是删除的记录在视图中只有主键,其余的字段都为空,这样基于日志视图上的过滤,必然导致删除的数据被过滤掉。以下是ODI创建的对象脚本示例:
数据源日志视图jv$qp_list_lines
create or replace view soau.jv$qp_list_lines as
SELECT decode(targ.ROWID, NULL, 'D', 'I') jrn_flag,
jrn.jrn_subscriber jrn_subscriber,
jrn.jrn_date jrn_date,
jrn.list_line_id list_line_id,
targ.creation_date creation_date,
targ.created_by created_by,
...
FROM (SELECT l.jrn_subscriber jrn_subscriber, l.list_line_id list_line_id, MAX(l.jrn_date) jrn_date
FROM soau.j$qp_list_lines l
WHERE l.jrn_consumed = '1'
GROUP BY l.jrn_subscriber, l.list_line_id) jrn,
soau.qp_list_lines targ
WHERE jrn.list_line_id = targ.list_line_id(+)
ODI Interface创建用于装载数据的的临时视图
create or replace view
SOAU.C$_0QP_LIST_LINES
(
C1_LIST_LINE_ID,
C2_CREATION_DATE,
C3_CREATED_BY,
...
JRN_SUBSCRIBER,
JRN_FLAG,
JRN_DATE
)
as select
QP_LIST_LINES.LIST_LINE_ID,
QP_LIST_LINES.CREATION_DATE,
QP_LIST_LINES.CREATED_BY,
...
JRN_SUBSCRIBER,
JRN_FLAG,
JRN_DATE
from SOAU.JV$QP_LIST_LINES QP_LIST_LINES
where (1=1)
And (QP_LIST_LINES.LIST_LINE_TYPE_CODE IN ('PLL', 'PBH'))
And (QP_LIST_LINES.END_DATE_ACTIVE is null or trunc(QP_LIST_LINES.END_DATE_ACTIVE) > trunc(sysdate))
And (QP_LIST_LINES.PRICING_PHASE_ID = 1)
And (QP_LIST_LINES.QUALIFICATION_IND IN (4, 6, 20, 22))
AND JRN_SUBSCRIBER = 'ERP-FK' /* AND JRN_DATE < sysdate */
当
Interface在执行集成时,将数据从视图SOAU.C$_0QP_LIST_LINES插入到flow table(flow
table是Interface处理的位于目标中间表,数据的同步最终从flow
table到目标数据表),由于该视图已经执行了过滤,删除的数据就无法插入到flow table,导致删除的数据最终无法写入目标。
三、问题解决过程
因为数据在源头就被过滤了,所以必须保证数据在源头不被过滤,而Interface可以支持在源、Staging、目标来执行处理,那么就来做各种测试:
1、将数据过滤移到Staging
经过测试发现,虽然在装载数据时,包含了删除的记录,但是在集成阶段,数据插入flow table时,由于除了主键,其余字段都为空,所以删除的数据同样被过滤掉了。
2、将数据过滤移到目标
经过测试,当我们将过滤移到目标时,删除的数据被正确的同步到了目标表。那只要将过滤移到目标,就可以解决问题了?
3、新问题的出现
实际上数据插入flow table后,从flow table到目标表,没有执行任何过滤处理,所有数据都会被同步到目标数据表。这样我们需要排除的数据也写入了目标表,说明这个方式失败。
4、启用模型中目标表的过滤
在ODI Designer中,编辑Model下的表,添加过滤,然后将Interface中对源数据的过滤移除,执行Interface发现,数据正确的插入到了目标表。但是这种方式和前一种方式相同,都是把所有变化的数据都从源取到目标中,存在一定的性能问题。
5、最终的方式
经过研究,还是觉得修改ODI原来的LKM最为实际,只需要把从日志视图的取数的视图代码修改,修改为原来的视图代码UNION删除的记录即可。
修改后的Create view on source代码如下:
create or replace view <%=odiRef.getObjectNameDefaultPSchema("L", "" , "W")%><%=odiRef.getInfo("COLL_NAME")%>
(
<%=odiRef.getColList("", "[CX_COL_NAME]", ",/n/t", "", "")%>
)
as select <%=odiRef.getPop("DISTINCT_ROWS")%>
<%=odiRef.getColList("", "[EXPRESSION]", ",/n/t", "", "")%>
from <%=odiRef.getFrom()%>
where (1=1)
<%=odiRef.getFilter()%>
<%=odiRef.getJrnFilter()%>
<%=odiRef.getJoin()%>
<%=odiRef.getGrpBy()%>
<%=odiRef.getHaving()%>
<%if(!odiRef.getJrnFilter().equals("")){%>
UNION
select <%=odiRef.getPop("DISTINCT_ROWS")%>
<%=odiRef.getColList("", "[EXPRESSION]", ",/n/t", "", "")%>
from <%=odiRef.getFrom()%>
where (1=1)
<%=odiRef.getJrnFilter()%>
AND JRN_FLAG='D'
<%=odiRef.getJoin()%>
<%=odiRef.getGrpBy()%>
<%=odiRef.getHaving()%>
<%}%>
四、插曲
在问题有了解决方案之后,向Oracle提Tar,经过数次沟通,并最终在OWC演示的情况下,确认为KM的Bug。
不过Oracle又提供了一种处理方法,这种方法不需要修改LKM,但是看上去感觉总有点不那么好:在Interface中的每个Filter代码中,加入" OR JRN_FLAG = 'D'",这样就可以保证日志表中删除的记录一定不会被过滤掉。
本文转自:http://www.itjaj.com/viewthread.PHP?tid=4590&extra=page%3D1%26amp%3Bfilter%3Dtype%26amp%3Btypeid%3D88
ODI中删除数据的处理的更多相关文章
- NHibernate 中删除数据的几种方法
今天下午有人在QQ群上问在NHibernate上如何根据条件删除多条数据,于是我自己就写了些测试代码,并总结了一下NHibernate中删除数据的方式,做个备忘.不过不能保证囊括所有的方式,如果还有别 ...
- 总结NHibernate 中删除数据的几种方法
今天下午有人在QQ群上问在NHibernate上如何根据条件删除多条数据,于是我自己就写了些测试代码,并总结了一下NHibernate中删除数据的方式,做个备忘.不过不能保证囊括所有的方式,如果还有别 ...
- SQL语句的使用,SELECT - 从数据库表中获取数据 UPDATE - 更新数据库表中的数据 DELETE - 从数据库表中删除数据 INSERT INTO - 向数据库表中插入数据
SQL DML 和 DDL 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). SQL (结构化查询语言)是用于执行查询的语法. 但是 SQL 语言也包含用于更新. ...
- GDAL书籍中删除数据勘误(C#语言)
GDAL书籍中关于C#版本删除数据的时候,不能完全删除数据,由于我对C#不了解导致代码有点问题,非常感谢@Bingoyin指出并给出修改方案.此外对于栅格图像的删除.重命名,矢量数据的删除和重命名都有 ...
- MySQL中删除数据的两种方法
转自:http://blog.csdn.net/apache6/article/details/2778878 1. 在MySQL中有两种方法可以删除数据: 一种是delete语句,另一种是trunc ...
- SQL语句中—删除数据
老大------drop 出没场合:droptable tb --tb表示数据表的名字,下同 绝招:删除内容和定义,释放空间.简单来说就是把整个表去掉.以后要新增数据是不可能的,除非新增一个表 老二- ...
- map在遍历数据的过程中删除数据不出错
// Iterator<Map.Entry<String,Long>> entries = Map.entrySet().iterator(); ...
- telerik:RadGrid 表格中删除数据
<telerik:RadGrid OnItemCommand=" Height="490px" Culture="zh-CN" CssClass ...
- Sql Server删除数据表中重复记录 三种方法
本文介绍了Sql Server数据库中删除数据表中重复记录的方法. [项目]数据库中users表,包含u_name,u_pwd两个字段,其中u_name存在重复项,现在要实现把重复的项删除![分析]1 ...
随机推荐
- jsp页面适应手机页面
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scal ...
- 图的最短路径问题————树上奶牛(tree.cpp)
和往常一样,继续从题目引入 树上奶牛 (tree.cpp) [题目描述] 农夫John的奶牛不是住在地上而是住在树上的QWQ. 奶牛之间需要串门,不过在串门之前他们会向John询问距离的大小.可是Jo ...
- Linux命令--链接文件的那些事
linux 链接ln的使用 linux操作系统下ln的使用方式: ln [option] source_file dest_file #source_file是待建立链接文件的文件,dest_file ...
- 浏览器文档播放Shockwave Flash 插件问题
浏览器被提示shockwave flash crashed怎么办?在使用浏览器的时候经常被提示shockwave flash crashed,flash插件崩溃,网页就会出现一些无法显示的文件,下面绿 ...
- Eclipse用link方式安装插件
其实eclipse安装插件更方便的方法就是直接扔到eclipse目录下的dropins文件夹,但如果插件比较多或者大的话,会让eclipse变得臃肿.下面介绍的用link方式可以避免这样的问题. 用l ...
- SQLServer 2008 R2 清空日志文件
USE [master]GOALTER DATABASE FH2_SJH SET RECOVERY SIMPLE WITH NO_WAITGOALTER DATABASE FH2_SJH SET RE ...
- PHP简易计算器方法1
<?phpheader("content-type:text/html;charset=utf-8");session_start();?><!DOCTYPE h ...
- C# 单向链表数据结构 (一)
单向链表数据结构是有节点组成,每个节点包含两部分,第一部分为存储数据,第二部分为指向下一个节点的指针.注意,有两个特色的节点,分别为“头节点”和“尾节点”,头节点本身没有数据,只存储下一个节点的指针, ...
- 【OpenGL游戏开发之三】OpenGl核心函数库汇总
OpenGl核心函数库 glAccum 操作累加缓冲区 glAddSwapHintRectWIN 定义一组被SwapBuffers拷贝的三角形 glAlphaFunc允许设置alpha检测功能 glA ...
- c语言结构体排序示例
设计性实验编程实现对学生成绩表的相关信息排序.实验要求:⑴ 建立一个由n个学生的考试成绩表,每条信息由学号.姓名和分数组成.⑵ 按学号排序,并输出排序结果.⑶ 按分数排序,分数相同的则按学号有序,并输 ...