目1 引言
本文档的编写是为了解决在集成过程中经常遇到的Clob类型的集成问题。这里是通过编写Jython代码,将代码嵌入到KM中,实现Clob类型数据的抽取。
缩写、术语
|
解 释
|
Clob
|
Character Large Object,字符型大对象,主要用于存储内容较长的文本。
|
|
|
|
|
与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操作的。
我们先在ODI中打开LKM sql to sql(Jython),双击打开步骤Load data (JYTHON),
同样,加入一段elif代码,如图:
加入的代码如下:
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),
打开它的表达式编辑器,查看它的代码,可以看到一些诸如如下代码的语句
elif colType == sql.Types.CHAR:
resline=rqteSrc.getString(nb+1)
psmt.setString(nb+1,resline)
这些语句的功能是对针对不同的数据类型采取不一样的类型判断。因此,我们在改写这个KM时,只需要将处理Blob类型的语句加入其中就可以实现对Blob的读取了。
因此,在这些elif语句中,加入了一行新的elif,如图:
加入的代码如下:
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
此IKM与Blob集成所用的IKM一样,都是采用的IKM Oracle Incremental Update Lob(删除了minus操作)。做实施时,可以将此KM导入即可。
创建接口INT_CLOB_ORA_TO_ORA,实现Clob数据从Oracle到Oracle的集成。
在“流”标签页中选择编辑好的KM:
“确定”,完成接口的创建。
执行接口,在Operator中查看,
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
分享到:
相关推荐
KM_IKM Oracle Incremental UpdateLOB.xml KM_LKM SQL to SQL LOB(JYTHON).xml 里面包含两个KM 可以直接用
LKM_SQL_to_Oracle_(CLOB)_v1.zip
Oracle ODI使用手册 详细讲解如何使用Oracle ODI
主要说明了oracle 的中间件软件odi的一般性能、作用和其逻辑框架等
Oracle ODI 11g 官方教程
自己基于最新的ODI 11g写的开发手册,非常详细基本每步都做了截图,高级开发部分会后续加进去
使用ODI写的文档,给其他人一些帮助。配置、过程、使用
Oracle 提供的一个数据集成工具开发培训资料
ODIPV 安装中文文档
OD是Oracle在2006年10月收购Sunopsis公司后,整合Sunopsis Active Integration Platform而推出的一款数据集成工具,现在是Oracle Fusion Middleware的组件。
Oracle+ODI+ESSBASE+BIEE
at oracle.odi.core.datasource.support.DefaultDataSourceManager.createAndConfigureDataSourceProvider(Unknown Source) at oracle.odi.core.datasource.support.DefaultDataSourceManager$1.create(Unknown ...
ODI用户指南,为学习ODI的朋友提供方便,总共分六大章节介绍