完美解决Kettle导数据库产生的中文乱码

本文介绍使用Kettle处理数据库间不同字符集导致的中文乱码问题。通过启用懒转换功能,保持数据原有字符集,避免乱码。此外,文章还提供了解决乱码的其他方法,包括设置数据库连接的字符集。
如果公司内一开始没有好好规划数据库建设,那么后期可能存在多种字符集的数据库实例。在做数据仓库或者来回导数据的时候,因字符集导致中文乱码问题困扰着不少人。网上有很多前辈们总结的解决中文乱码的方案,关于使用kettle如何解决也有一两篇谈到在建数据库连接时加characterEncoding来解决。我昨晚找到另外一种方式来跟大家分享:

 

经过对源码搜索”encoding“,找一句注释,发现其实解决方法很简单,

Java代码 复制代码  收藏代码
  1. /**  
  2.  * Build the row using ResultSetMetaData rsmd  
  3.     * @param rm The resultset metadata to inquire  
  4.     * @param ignoreLength true if you want to ignore the length (workaround for MySQL bug/problem)  
  5.     * @param lazyConversion true if lazy conversion needs to be enabled where possible  
  6.  */  
  7. private RowMetaInterface getRowInfo(ResultSetMetaData rm, boolean ignoreLength, boolean lazyConversion) throws KettleDatabaseException   
  8. {   
  9.        if (rm==nullreturn null;   
  10.        
  11.     rowMeta = new RowMeta();   
  12.        
  13.     try  
  14.     {   
  15.         // TODO If we do lazy conversion, we need to find out about the encoding   
  16.         //   
  17.            int fieldNr = 1;   
  18.         int nrcols=rm.getColumnCount();    
  19.         for (int i=1;i<=nrcols;i++)   
  20.         {   
  21.             String name=new String(rm.getColumnName(i));   
  22.                   
  23.                // Check the name, sometimes it's empty.   
  24.                //   
  25.                if (Const.isEmpty(name) || Const.onlySpaces(name))   
  26.                {   
  27.                    name = "Field"+fieldNr;   
  28.                    fieldNr++;   
  29.                }   
  30.                   
  31.             ValueMetaInterface v = getValueFromSQLType(name, rm, i, ignoreLength, lazyConversion);   
  32.             rowMeta.addValueMeta(v);               
  33.         }   
  34.         return rowMeta;   
  35.     }   
  36.     catch(SQLException ex)   
  37.     {   
  38.         throw new KettleDatabaseException("Error getting row information from database: ", ex);   
  39.     }   
  40. }  
	/**
	 * Build the row using ResultSetMetaData rsmd
     * @param rm The resultset metadata to inquire
     * @param ignoreLength true if you want to ignore the length (workaround for MySQL bug/problem)
     * @param lazyConversion true if lazy conversion needs to be enabled where possible
	 */
	private RowMetaInterface getRowInfo(ResultSetMetaData rm, boolean ignoreLength, boolean lazyConversion) throws KettleDatabaseException
	{
        if (rm==null) return null;
		
		rowMeta = new RowMeta();
		
		try
		{
			// TODO If we do lazy conversion, we need to find out about the encoding
			//
            int fieldNr = 1;
			int nrcols=rm.getColumnCount();	
			for (int i=1;i<=nrcols;i++)
			{
				String name=new String(rm.getColumnName(i));
                
                // Check the name, sometimes it's empty.
                //
                if (Const.isEmpty(name) || Const.onlySpaces(name))
                {
                    name = "Field"+fieldNr;
                    fieldNr++;
                }
                
				ValueMetaInterface v = getValueFromSQLType(name, rm, i, ignoreLength, lazyConversion);
				rowMeta.addValueMeta(v);			
			}
			return rowMeta;
		}
		catch(SQLException ex)
		{
			throw new KettleDatabaseException("Error getting row information from database: ", ex);
		}
	}

 就是这样”If we do lazy conversion, we need to find out about the encoding“,直接勾选”允许延迟转换“即可:

这样在从数据库读取的数据就能保持原有字符集,不因默认强制使用utf8导致乱码,在输出时指定文件字符集,就会解决导出到文件中的乱码问题。

如果导入到目标表的字符集与源表不同,需要在入库前用select values做字符转换(纯属废话,相同就不会有乱码了):

 

整个流程如下

这样,无论到文件还是目标表,都不会再有乱码了。

 

 

如果以上还无法解决,可以在Table Input 和Table Output的数据库连接高级选项中设置当前session的字符集;以下除了可以设置session 的字符集,还可以设置日期格式等。

 

通过以上设置还无法解决,只能归结为RP不好了O(∩_∩)O~

在使用 Kettle数据库查询组件时,出现乱码问题通常是由于字符编码设置不当致的。以下是一些可行的解决方案,结合了实际使用场景和技术调整手段。 ### 修改数据库连接参数 在部分情况下,即使数据库中的数据显示正常,但在 Kettle 的表输入组件中预览时仍可能出现乱码。这是由于 Kettle数据库之间的连接未正确设置字符集所致。可以在数据库连接的配置中手动指定字符编码,例如对于 MySQL 数据库,可以在连接字符串的参数部分添加字符集设置: ``` jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=UTF-8 ``` 确保 `characterEncoding` 参数的值与数据库实际使用的字符集一致,例如 `UTF-8`、`GBK` 等 [^2]。 ### 调整 Kettle 启动文件的编码设置 Kettle 本身的启动脚本也可以通过设置 JVM 参数来控制默认的文件编码,从而影响整个 Kettle 环境的字符处理方式。对于 Linux 系统,可以编辑 `spoon.sh` 文件,在 `OPT` 变量中加入以下参数: ``` -Dfile.encoding=GBK ``` 这样可以强制 Kettle 使用 GBK 编码进行文件处理,适用于中文乱码的情况 [^3]。 对于 Windows 系统,可以修改 `spoon.bat` 文件,调整 `PENTAHO_DI_JAVA_OPTIONS` 变量内容,添加字符编码设置: ``` set PENTAHO_DI_JAVA_OPTIONS="-Xms1024m" "-Xmx2048m" "-Dfile.encoding=GBK" ``` 此设置将确保 Kettle 在启动时使用 GBK 编码,以避免中文乱码问题 [^4]。 ### 检查数据源和目标的编码一致性 除了 Kettle 本身的设置,还应确保源数据库和目标文件或数据库的字符集一致。例如,如果源数据库使用 UTF-8 编码,而目标 Excel 文件保存为 GBK 编码,则可能出现乱码。可以在数据时指定目标文件的编码格式,或者在目标系统中调整默认字符集设置。 ### 总结 解决 Kettle 数据库查询组件乱码问题的关键在于确保从数据库连接、Kettle 启动参数到数据目标编码的整个流程中,字符集设置保持一致。通过调整连接字符串参数、Kettle 启动配置以及目标存储的编码方式,可以有效避免乱码问题的发生。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值