`
shangjava
  • 浏览: 1191539 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

ODI Oracle Lob类型的处理

阅读更多

1 引言

1.1 编写目的

本文档的编写是为了解决在集成过程中经常遇到的Clob类型的集成问题。这里是通过编写Jython代码,将代码嵌入到KM中,实现Clob类型数据的抽取。

1.2 术语定义

缩写、术语

Clob

Character Large Object,字符型大对象,主要用于存储内容较长的文本。

2 处理思路

与Blob的类似,在LKM sql to sql (Jython)中并未指定对Clob的处理方法。所以,我们同样需要将对Clob的处理方式加入到Jython代码中。

同样,与Blob的处理方式类似,对Clob同样需要先转化为流——字符流。在java中,Clob是这样进行处理的:

getCharacterStream(int columnIndex)

setCharacterStream(int parameterIndex,Reader reader,Int length)

总的处理思路还是与Blob类似:

1. 将Clob数据以字符流的形式读出。

2. 判断读出的Clob是否为空,如果为空,则直接以setCharacterStream输出,length指定为0。如果非空,则将字节流读入到一个缓冲数组,再将缓冲数组读入到一个输出流中,获取输出流的长度(转为字符数组可得到长度),然后就可以通过set方法将输出流写入临时区域的Clob字段。

虽然处理的思路相同,但引用的方法却不同,这点将在接下来介绍。

另外,Clob和Blob一样,都不能进行“==”比较和在minus、distinct、group by等子句中出现,所以同样要用到IKM Oracle Incremental Update Lob,这个KM中是删除了minus操作的。

3 编辑KM以处理Clob

3.1 编辑LKM sql to sql Clob(Jython)

我们先在ODI中打开LKM sql to sql(Jython),双击打开步骤Load data (JYTHON),

clip_image002

同样,加入一段elif代码,如图:

clip_image004

加入的代码如下:

elif colType == sql.Types.CLOB: #Code 2001

resline=rqteSrc.getCharacterStream(nb+1)

if resline:

ary = jarray.zeros(1024,'c')

r = resline.read(ary)

out = CharArrayWriter()

while (r >= 0) :

out.write(ary,0,r)

r = resline.read(ary)

try:

instream = CharArrayReader(out.toCharArray())

length = len(out.toCharArray())

psmt.setCharacterStream(nb+1,instream,length)

except java.lang.Exception,e:

print e.getLocalizedMessage().encode("utf-8")

elif not resline:

psmt.setCharacterStream(nb+1,resline,0)

现在来分析这段代码,

1. resline=rqteSrc.getCharacterStream(nb+1),这是对字符流的处理方式,与字节流不同。

2. ary = jarray.zeros(1024,'c'),这里是‘c’,不是Blob用的‘b’。

3. out = CharArrayWriter(),这是生成字符输出流的方式,有别于Blob的out = ByteArrayOutputStream()

4. instream = CharArrayReader(out.toCharArray()),生成字符输入流。

5. out.toCharArray()生成字符数组,Blob中是out.toByteArray()。

这段代码可对照Blob的处理代码来看,也可对照文档《Blob类型的集成》来看。

引用的包有:

from java.io import CharArrayWriter

from java.io import CharArrayReader

最后,将LKM保存并重命名为LKM sql to sql Clob(Jython)。

我们先在ODI中打开LKM sql to sql(Jython),双击打开步骤Load data (JYTHON),

clip_image005

打开它的表达式编辑器,查看它的代码,可以看到一些诸如如下代码的语句

elif colType == sql.Types.CHAR:

resline=rqteSrc.getString(nb+1)

psmt.setString(nb+1,resline)

这些语句的功能是对针对不同的数据类型采取不一样的类型判断。因此,我们在改写这个KM时,只需要将处理Blob类型的语句加入其中就可以实现对Blob的读取了。

因此,在这些elif语句中,加入了一行新的elif,如图:

clip_image007

加入的代码如下:

elif colType == sql.Types.BLOB: #Code 2000

resline=rqteSrc.getBinaryStream(nb+1)

if resline:

buffer = jarray.zeros(1024,'b')

r = resline.read(buffer)

out = ByteArrayOutputStream()

while (r >= 0) :

out.write(buffer,0,r)

r = resline.read(buffer)

try:

instream = ByteArrayInputStream(out.toByteArray())

length = len(out.toByteArray())

psmt.setBinaryStream(nb+1,instream,length)

except java.lang.Exception,e:

print e.getLocalizedMessage().encode("utf-8")

elif not resline:

psmt.setBinaryStream(nb+1,resline,0)

这里的语法采用的是Jython的语法,Jython语言与其它语言有些不同,它不以分号来标识一行代码的结束,只用换行就可以,另外,Jython使用空格缩进,来识别程序的分组和级别,例如上面的代码中,第三行的if和倒数第二行的elif,他们的起始符都是用了6个空格缩进,这样Jython才能识别这个if和elif属于同一分组,这点非常重要。

现在来分析这段代码,

1. elif colType == sql.Types.BLOB,判断字段类型是否为Blob;

2. resline=rqteSrc.getBinaryStream(nb+1),将数据以字节流的方式读出,代码最后的psmt.setBinaryStream(nb+1,instream,length)表示将instream写入目标。

3. if resline表示判断resline是否为空,buffer = jarray.zeros(1024,'b')表示创建一个buffer数组,‘b’代表存储的是字节型,1024是数组长度(1KB)。

4. r = resline.read(buffer)将resline写入buffer数组,r表示读入的字节数。

5. out = ByteArrayOutputStream()

while (r >= 0) :

out.write(buffer,0,r)

r = resline.read(buffer)

这段生成一个out输出流。实际上,将resline读入out中,每次都是读1KB,直至读完为止,while语句的功能就是如此,当r为null时,停止循环。

6. instream = ByteArrayOutputStream (out.toByteArray())表示将out生成一个输入流。

7. length = len(out.toByteArray())表示获取输出流out的长度,也就是Blob字段的大小。

8. elif not resline表示当resline为null时怎么处理。判断resline是否为null一定要加入代码,不然,一味用ByteArrayOutputStream和ByteArrayOutputStream的方法处理,会导致在执行r = resline.read(buffer)时报错。

因为在这段Jython代码中引用了一些java的方法,因此在代码最开始的部分,要将这些包import进来。所以最开始要加入如下代码:

import jarray

from java.io import ByteArrayOutputStream

from java.io import ByteArrayInputStream

3.2 编辑IKM Oracle Incremental Update Lob

此IKM与Blob集成所用的IKM一样,都是采用的IKM Oracle Incremental Update Lob(删除了minus操作)。做实施时,可以将此KM导入即可。

4 创建接口

创建接口INT_CLOB_ORA_TO_ORA,实现Clob数据从Oracle到Oracle的集成。

clip_image009

clip_image011

在“流”标签页中选择编辑好的KM:

clip_image013

clip_image015

“确定”,完成接口的创建。

执行接口,在Operator中查看,

clip_image017

5 其它

LKM sql to sql Clob(Jython)用于处理Oracle的Clob字段。如果是其他数据库的字符型大对象字段,例如SQL Server的text、ntext类型,可以采用相同的处理思想来实现数据的加载——即转为字符流来判断字段长度,并将数据读出。

IKM Oracle Incremental Update Lob也仅适用于Oracle的Lob集成,其他数据库的集成时所需的IKM还需要重新编辑。

LKM sql to sql Clob(Jython)和IKM Oracle Incremental Update Lob都已放置在配置库中,在实施中可直接导入ODI中使用。

本文转自:http://dangdj.spaces.live.com/?_c11_BlogPart_pagedir=Next&_c11_BlogPart_handle=cns!EDE097CEA39ABC75!204&_c11_BlogPart_BlogPart=blogview&_c=BlogPart

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics