学习使用kettle,在学习的过程中遇到一些连接数据库的问题,经过一番努力之后,终于找到解决方案,现将遇到的问题和解决方案公布如下,有不对的地方请大家指正。

问题一:用spoon设计了一个转换,主要功能是从数据文件中读取记录,然后直接存入数据库(我们使用的是IBM DB2)。在执行转换的过程中,遇到了如下异常:

2006/11/03 16:04:12 - 数据库输出.0 - ERROR (version 2.3.1, build 63 from 2006/09/14 12:04:05 @ sam) : An error occurred intialising this step:

2006/11/03 16:04:12 - 数据库输出.0 - ERROR (version 2.3.1, build 63 from 2006/09/14 12:04:05 @ sam) : Error occured while trying to connect to the database

2006/11/03 16:04:12 - 数据库输出.0 - ERROR (version 2.3.1, build 63 from 2006/09/14 12:04:05 @ sam) :

2006/11/03 16:04:12 - 数据库输出.0 - ERROR (version 2.3.1, build 63 from 2006/09/14 12:04:05 @ sam) : Error connecting to database: (using class com.ibm.db2.jcc.DB2Driver)

2006/11/03 16:04:12 - 数据库输出.0 - ERROR (version 2.3.1, build 63 from 2006/09/14 12:04:05 @ sam) : Unicode string can't convert to Ebcdic string

2006/11/03 16:04:12 - 数据库输出 - ERROR (version 2.3.1, build 63 from 2006/09/14 12:04:05 @ sam) : 错误初始化步骤[数据库输出]

2006/11/03 16:04:12 - be.ibridge.kettle.trans.Trans - ERROR (version 2.3.1, build 63 from 2006/09/14 12:04:05 @ sam) : !Trans.Log.StepFailedToInit!

2006/11/03 16:04:12 - be.ibridge.kettle.trans.Trans - ERROR (version 2.3.1, build 63 from 2006/09/14 12:04:05 @ sam) : 无法初始化至少一个步骤. 执行无法开始!

在遇到该异常之前,我已经对数据库连接进行了测试,完全可以正常连接。之后我又使用spoon的SQL编辑器连接数据库并插入记录,仍然没有任何异 常。换为连接MySql然后执行该转换也没有问题,数据可以正常的写入数据库。我们首先考虑到的是spoon使用的字符集和DB2的字符集不匹配。于是更 改数据库的字符集,将其改为utf-8,然后再执行转换,依然抛出上面的异常。后来在查阅资料的时候发现DB2 type 4的jdbc驱动可能存在字符编码转换的问题,于是察看spoon使用的DB2 jdbc驱动的类型,正是type4的驱动!于是考虑配置spoon,使其使用type3的jdbc驱动,让我们郁闷的是spoon里根本没有对驱动类型 进行配置的地方!无奈中,我们找出了kettle的源码,几经周折,最终在be.ibridge.kettle.core.database包中的 DB2DatabaseMeta.java文件中找到了kettle的DB2连接配置,源程序如下:

public String getDriverClass()

...{

if (getAccessType()==DatabaseMeta.TYPE_ACCESS_ODBC)

...{    return "sun.jdbc.odbc.JdbcOdbcDriver";   }

else

...{

return "com.ibm.db2.jcc.DB2Driver";

}

}

public String getURL()

...{

if (getAccessType()==DatabaseMeta.TYPE_ACCESS_ODBC)

...{

return "jdbc:odbc:"+getDatabaseName();

}

else

...{

return "jdbc:db2://"+getHostname()+":"+getDatabasePortNumberString()+"/"+getDatabaseName();

}

}对这两个方法进行修改,改为以下代码: public String getDriverClass()

...{

if (getAccessType()==DatabaseMeta.TYPE_ACCESS_ODBC)

...{return "sun.jdbc.odbc.JdbcOdbcDriver";}

else

...{return "com.ibm.db2.jdbc.net.DB2Driver";}

}

public String getURL()

...{

if (getAccessType()==DatabaseMeta.TYPE_ACCESS_ODBC)

...{return "jdbc:odbc:"+getDatabaseName();}

else

...{return "jdbc:db2:"+getHostname()+":"+getDatabaseName();}

编译修改后的文件,用新的DB2DatabaseMeta.class代替kettle原来的文件,重新打包(注意要把DB2自带的驱动程序包也打进去),重新运行该转换,一切ok啦!

问题二:无论使用spoon还是使用chef的时候都会询问你有没有资源库,第一次运行时当然是没有了,那么就新建吧。这时,让人郁闷的东西出现了,在向数据库(这里还是DB2 啦)中建表的时候会出现如下异常,导致资源库创建失败:

Couldn't execute SQL: CREATE TABLE R_NOTE

(

ID_NOTE DECIMAL(9)

, VALUE_STR CLOBBLOB(2000000) UNKNOWN

, GUI_LOCATION_X DECIMAL(6)

, GUI_LOCATION_Y DECIMAL(6)

, GUI_LOCATION_WIDTH DECIMAL(6)

, GUI_LOCATION_HEIGHT DECIMAL(6)

)

DB2 SQL error: SQLCODE: -104, SQLSTATE: 42601, SQLERRMC: CLOBBLOB;IMAL(9) , VALUE_STR;

java.lang.reflect.InvocationTargetException: Error creating or upgrading repository:

Couldn't execute SQL: CREATE TABLE R_NOTE

(

ID_NOTE DECIMAL(9)

, VALUE_STR CLOBBLOB(2000000) UNKNOWN

, GUI_LOCATION_X DECIMAL(6)

, GUI_LOCATION_Y DECIMAL(6)

, GUI_LOCATION_WIDTH DECIMAL(6)

, GUI_LOCATION_HEIGHT DECIMAL(6)

)

DB2 SQL error: SQLCODE: -104, SQLSTATE: 42601, SQLERRMC: CLOBBLOB;IMAL(9) , VALUE_STR;

at be.ibridge.kettle.repository.dialog.UpgradeRepositoryProgressDialog$1.run(UpgradeRepositoryProgressDialog.java:66)

at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:346)

at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:291)

at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:447)

at be.ibridge.kettle.repository.dialog.UpgradeRepositoryProgressDialog.open(UpgradeRepositoryProgressDialog.java:74)

at be.ibridge.kettle.repository.dialog.RepositoryDialog.create(RepositoryDialog.java:450)

at be.ibridge.kettle.repository.dialog.RepositoryDialog.access$800(RepositoryDialog.java:64)

at be.ibridge.kettle.repository.dialog.RepositoryDialog$5.handleEvent(RepositoryDialog.java:267)

at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)

at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:928)

at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3348)

at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2968)

at be.ibridge.kettle.repository.dialog.RepositoryDialog.open(RepositoryDialog.java:291)

at be.ibridge.kettle.repository.dialog.RepositoriesDialog$3.widgetSelected(RepositoriesDialog.java:297)

。。。more异常信息很长,但请大家注意上面红色标记的异常。CLOBBLOB(2000000) UNKNOWN 觉不觉的这个类型很奇怪?没错,就是它导致建表失败的。通过分析源码,最终还是在DB2DatabaseMeta.java中找到以下方法:

public String getFieldDefinition(Value v, String tk, String pk, boolean use_autoinc, boolean add_fieldname, boolean add_cr)

String retval="";

String fieldname = v.getName();

int    length    = v.getLength();

int    precision = v.getPrecision();

if (add_fieldname) retval+=fieldname+" ";

int type = v.getType();

switch(type)

...{

case Value.VALUE_TYPE_DATE   : retval+="TIMESTAMP"; break;

case Value.VALUE_TYPE_BOOLEAN: retval+="CHARACTER(1)"; break;

case Value.VALUE_TYPE_NUMBER :

case Value.VALUE_TYPE_INTEGER:

case Value.VALUE_TYPE_BIGNUMBER:

if (fieldname.equalsIgnoreCase(tk) && use_autoinc) // Technical key: auto increment field!

...{

retval+="BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 0, INCREMENT BY 1, NOCACHE)";

}

else

...{

if (length>0)

...{

retval+="DECIMAL("+length;

if (precision>0)

...{

retval+=", "+precision;

}

retval+=")";

}

else

...{

retval+="FLOAT";

}

}

break;

case Value.VALUE_TYPE_STRING:

if (length>getMaxVARCHARLength() || length>=DatabaseMeta.CLOB_LENGTH)

...{

retval+="CLOB";

}

else

...{

retval+="VARCHAR";

if (length>0)

...{

retval+="("+length;

}

else

...{

retval+="("; // Maybe use some default DB String length?

}

retval+=")";

break;

}

case Value.VALUE_TYPE_BINARY:

if (length>getMaxVARCHARLength() || length>=DatabaseMeta.CLOB_LENGTH)

...{

retval+="BLOB("length")";

}

else

...{

if (length>0)

...{

retval+="CHAR("length") FOR BIT DATA";

}

else

...{

retval+="BLOB"; // not going to work, but very close

}

break;

}

default:

retval+=" UNKNOWN";

break;

}

if (add_cr) retval+=Const.CR;

return retval;

}注意方法中红色标记的部分,在这里竟然出现了严重的逻辑错误:case语句里并不是每个分支都有break;因此当有满足Value.VALUE_TYPE_STRING分支的if语句的条件出现,就会顺序执行后面所有的分支(注意,满足Value.VALUE_TYPE_STRING分支的if语句的条件同样也满足Value.VALUE_TYPE_BINARY 分支的if语句的条件)。这就导致了最终的字符串变成了我们前面看到的那个奇怪的数据库字段类型。那么解决方法就简单了,修改的代码如下:

case Value.VALUE_TYPE_STRING:

if (length>getMaxVARCHARLength() || length>=DatabaseMeta.CLOB_LENGTH)

...{

retval+="CLOB";

}

else

...{

retval+="VARCHAR";

if (length>0)

...{

retval+="("+length;

}

else

...{

retval+="("; // Maybe use some default DB String length?

}

retval+=")";

}   break;

case Value.VALUE_TYPE_BINARY:

if (length>getMaxVARCHARLength() || length>=DatabaseMeta.CLOB_LENGTH)

...{

retval+="BLOB("length")";

}

else

...{

if (length>0)

...{

retval+="CHAR("length") FOR BIT DATA";

}

else

...{

retval+="BLOB"; // not going to work, but very close

}

}break;default: 。。。。。。这样就好了,不过第二个问题好像kettle现在的版本已经修改好了

kettle MySQL blob_KETTLE BLOB 问题相关推荐

  1. mysql++读写BLOB数据

    mysql++读写BLOB数据 1.使用sql_create_n宏函数,建立数据库表字段与对象.    #define sql_create_2(NAME, CMP, CONTR, T1, I1, T ...

  2. c语言 mysql_bind,linux C mysql的blob门类字段的插入和读取

    linux C mysql的blob类型字段的插入和读取. RT,没对mysql中的这种类型操作过,还请各位大神帮帮忙,需要一点代码,确实有点急,网上看了一些,但是没怎么看懂.还望指导,多谢!! my ...

  3. mysql数据库blob换行_mysql数据库blob类型

    Java -- JDBC 学习--处理Blob Oracle LOB LOB,即Large Objects(大对象),是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储可多达4GB的 ...

  4. kettle mysql 参数,Kettle集群及Mysql参数调整

    <Kettle集群及Mysql参数调整>由会员分享,可在线阅读,更多相关<Kettle集群及Mysql参数调整(10页珍藏版)>请在人人文库网上搜索. 1.1 Kettle 集 ...

  5. mysql 查看blob字段大小_MYSQL BLOB 字段大小以及个数的限制测试。

    测试结论 mysql版本 5.1     表类型: innodb, row_format=compact (这是默认的行格式)     插入超过10个blob, blob的数据量很小(<768字 ...

  6. mysql中imagin的类型_Image转换成Mysql的blob类型 | 学步园

    发现网上好多方法都不可行,下面是我的方法,略麻烦,纯属为自己以后的使用做个记录,如果你有更好的方法请留言,谢谢~ 第二种方法,已知文件路径,通过构造文件的方式转换成blob很简单.如果很不幸,你只有I ...

  7. mysql数据库blob区别_MySQL中TEXT与BLOB字段类型的区别

    在MySQL中有两个字段类型容易让人感觉混淆,那就是TEXT与BLOB,特别是自己写博客程序的博主不知道改为自己的博客正文字段选择TEXT还是BLOB类型. 下面给出几点区别: 一.主要差别 TEXT ...

  8. kettle mysql 配置_Kettle数据库配置抽离

    在使用ETL工具Kettle时候,为了使作业或转换具有通用性,有时候,我们需要将数据库的连接配置从脚本或转换中抽离出来,下面介绍一种方案,该方案主要涉及的文件有: # 这两个文件,默认是在系统的用户目 ...

  9. mysql blob图片_使用mysql的Blob字段存取图片

    只是做实验,没有考虑buffer存取和性能. 建立表: CREATE TABLE example (name VARCHAR(100),city VARCHAR(100),image BLOB,Pho ...

  10. mysql数据库blob换行_mysql Blob存取的一个简单例子

    一.得到mysql的连接 这里封装成一个方法,方便后面使用. public Connection getConnection() throws Exception{ String url = &quo ...

最新文章

  1. 用Table变量返回多行数据
  2. 一个身份证号码验证接口[2]
  3. Dubbo的RPC原理
  4. java 纯面向对象_Java到底是不是一种纯面向对象语言?
  5. 希望直接访问系统内某个链接,跳过登录验证等过程
  6. 在UWP的XAML中使用原始类型
  7. 浅谈三角带的使用及其分类
  8. 设计篇-网页设计规范
  9. Mstar 光机遥控器适配
  10. XSS过滤绕过总结_xss绕过字符过滤
  11. lzw压缩 java_Java压缩之LZW算法字典压缩与解压讲解
  12. linux 命令运行kodi,在Ubuntu/Debian/Raspbian中安装Kodi for Linux的方法
  13. 为什么在抖音直播间打字别人看不见,所有抖音直播间看不见我说话
  14. Android 手机采集摄像头视频 socket 视频传输实时传播
  15. linux xunsou_IT外包 网络综合布线 机房建设整改 弱电集成安防-_295
  16. 【深度学习】数据分割
  17. Mac使用Marginnote3时,启动会自动打开固定某一个笔记解决方案
  18. 奥鹏刷分软件_奥鹏挂积分软件下载|
  19. 使用显卡训练DL4J的问题总结
  20. 计算机前置usb应用,电脑前面usb不能用的原因及解决办法

热门文章

  1. 互联网行业常见的需要考虑的问题
  2. myeclipse修改maven settings
  3. 【vivado】PL通过axi_hp接口控制PS的DDR
  4. RecyclerView更全解析之 为它优雅的添加头部和底部
  5. java伪代码 读后感
  6. Junit +cucumber 运行报错 initiallizationError
  7. mysql数据库忘记密码时如何修改
  8. 虚拟机中centos7 安装过程中没有自动获取到网络
  9. yum的更多用法和源码编译安装apache
  10. sql聚合函数及分组的注意事项