DataStage序列文章

DataStage 一、安装
DataStage 二、InfoSphere Information Server进程的启动和停止
DataStage 三、配置ODBC
DataStage 错误集(持续更新)
DataStage 四和五因为包含大量图片发布不便,有兴趣学习和研究者请联系索要!!!
DataStage 六、安装和部署集群环境
DataStage 七、在DS中使用配置文件分配资源
DataStage 八、清除日志

说明

默认情况下datastage 9.1版本中只支持Enterprise or Commercial版本的MySQL数据库,如果要使用MySQL Community版本数据库则可以通过安装和配置mysql-connector-odbc驱动来完成;以下的实验以datastage 9.1.0、MySQL Community 5.0.67 Edition和mysql驱动mysql-connector-odbc-5.3.4-1.el6.x86_64.rpm在Linux上实验为例。

1 安装MySQL ODBC驱动

在网上下载mysql-connector-odbc-5.3.4-1版本驱动,然后安装;

#rpm -ivh mysql-connector-odbc-5.3.4-1.el6.x86_64.rpm
Preparing... ########################################### [100%]
1:mysql-connector-odbc ########################################### [100%]
Success: Usage count is 1
Success: Usage count is 1

安装结束后得到如下目录和文件信息

/usr/share/doc/mysql-connector-odbc-5.3.4
/usr/share/mysql
/usr/lib64/mysql
/usr/lib64/mysql/libmysqlclient.so.16.0.0
/usr/lib64/mysql/libmysqlclient.so.16
/usr/lib64/mysql/libmysqlclient_r.so.16.0.0
/usr/lib64/mysql/libmysqlclient_r.so.16
/usr/lib64/libmyodbc5w.so
/usr/lib64/libmyodbc5a.so
/usr/bin/myodbc-installer

libmyodbc5w.so就是我们要用到的驱动文件。

2 配置ODBC

编辑$DSHOME/.odbc.ini文件,根据里面的示例创建mysql odbc;

[odbc_mysql]
Driver=/usr/lib64/libmyodbc5w.so
DriverUnicodeType=1
Description=DataDirect 7.0 MySQL Wire Protocol
Database=mysql
Server=150.18.44.99
User=root
Password=
Port=3306
QueryTimeout=0
ReportCodepageConversionErrors=0
TreatBinaryAsChar=0
TrustStore=
TrustStorePassword=
ValidateServerCertificate=1
Option=3

这里Driver指定新安装的驱动文件;
DriverUnicodeType指定字节长度,默认情况下datastage使用附带的DataDirect ODBC管理驱动和支持多种常用的数据库,但当使用第三方驱动时,第三方驱动与DataDirect ODBC可能不完全兼容,比如一般情况下ds DataDirect ODBC驱动使用4个字节长度的字符(比如UTF16),而第三方驱动使用2个字节长度的字符,这时如果不指定DriverUnicodeType则会发生Unicode converter buffer overflow错误;所以当在Driver下面设置了DriverUnicodeType属性时,DataDirect ODBC管理和维护统一的字节长度;
Server 指定服务器,不要弄错了,.odbc.ini文件中的示例是HostName;
Port指定端口;
接着将ODBC配置到项目目录下的uvodbc.config 文件中;

<odbc_mysql>
DBMSTYPE = ODBC

完成这些操作后再通过dssh测试odbc;

#dssh
DataStage Command Language 9.1 Licensed Materials - Property of IBM
(c) Copyright IBM Corp. 1997, 2012 All Rights Reserved.
dscluster logged on: Thursday, November 19, 2015 20:52 >logto dscluster
>ds_connect odbc_mysql
odbc_mysql> show tables;
Tables_in_mysql
---------------
char_test
columns_priv
db
func
help_category
help_keyword
help_relation
help_topic
host

3 乱码的产生

在一个字符集为AMERICAN_AMERICA.AL32UTF8的Oracle数据库中建立一张表并存入中文的数据;

create table char_test(
col1 varchar2(300),
col2 varchar2(50)
); insert into char_test(col1,col2) values('曹操','三国演义中的武王');
insert into char_test(col1,col2) values('刘备','三国演义中的蜀王');
insert into char_test(col1,col2) values('诸葛亮','三国演义中的军师');

在MySQL数据库中建立相同的数据表;

 create table char_test(
col1 varchar(300),
col2 varchar(50)
);

创建ds job完成oracle到mysql的数据交换;

数据交换完成后发现MySQL数据表中全是乱码;

mysql> select * from char_test;
+------+----------+
| col1 | col2 |
+------+----------+
| ?? | ???????? |
| ?? | ???????? |
| ??? | ???????? |
+------+----------+

4 乱码分析

根据MySQL文档得知,MySQL数据库可以在数据库层面、数据表层面、数据表列层面设置字符集,并且它们的设置都继承于上一级,所以如果在创建表时,没有为列指定字符集,则列继承于表的字符集;如果没有为表指定字符集,则表继承数据库的字符集。当客户端向服务端发送请求时字符将产生这样的转换过程(character_set_client(客户端来源数据使用的字符集)、character_set_connection(连接层字符集)、character_set_results(查询结果字符集)),so 根据这些来判断,首先想到的是MySQL数据库层面使用的字符集和字符序;

mysql> show variables like 'character%';
+--------------------------+--------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | D:\develope\MySQL5.0\share\charsets\ |
+--------------------------+--------------------------------------+ mysql> show variables like 'collation%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | utf8_general_ci |
| collation_database | latin1_swedish_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+

此时数据库使用的字符集和字符序都是latin1,而在创建表时均未指定列和表使用的字符集,所以数据表和数据表列都继承了数据库的字符集;

mysql> show table status like 'char_test';
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-----
----------------+-------------+------------+-------------------+----------+----------------+----------------------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Crea
te_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-----
----------------+-------------+------------+-------------------+----------+----------------+----------------------+
| char_test | InnoDB | 10 | Compact | 0 | 0 | 16384 | 0 | 0 | 0 | NULL | 2015
-11-20 10:59:49 | NULL | NULL | latin1_swedish_ci | NULL | | InnoDB free: 9216 kB |
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-----
----------------+-------------+------------+-------------------+----------+----------------+----------------------+
1 row in set (0.00 sec) mysql> show full columns from char_test;
+-------+--------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+-------+--------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
| col1 | varchar(300) | latin1_swedish_ci | YES | | NULL | | select,insert,update,references | |
| col2 | varchar(50) | latin1_swedish_ci | YES | | NULL | | select,insert,update,references | |
+-------+--------------+-------------------+------+-----+---------+-------+---------------------------------+---------+

所以当客户端插入中文字符时,MySQL数据库做了如下转换:
utf8=>utf8=>latin1
原始数据中含有的(\u0000 ~ \u00ff)范围以外的Unicode字符会因为无法在latin1字符集中表示而被转换为"?"(0x3f)符号,以后查询不管连接字符集如何设置都无法恢复其原始内容。

5 乱码的解决方法

在分析了数据库字符集和乱码原因后知道了乱码的产生的真正原因了,那如何处理呢?抱着这些问题我做了三种可行的设想和解决方法:
1. 将表的字符集从latin1转换为utf8;
2. 将数据库默认字符设置为utf8;
3. 创建数据库时明确指定字符集;

5.1 将表的字符集从latin1转换为utf8

这种实现方案主要是为了不影响系统运行和其它用户并且生产迫切急需的情况下进行的,相对来说它的影响最小,速度快。

alter table char_test default character set=utf8;
alter table char_test convert to character set utf8;

注意:命令1是把表的默认字符设置为utf8(不包括列哦),命令2是把表转换为utf8(包括列哦)

mysql> show table status like 'char_test';
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-----
----------------+-------------+------------+-----------------+----------+----------------+----------------------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Crea
te_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-----
----------------+-------------+------------+-----------------+----------+----------------+----------------------+
| char_test | InnoDB | 10 | Compact | 3 | 5461 | 16384 | 0 | 0 | 0 | NULL | 2015
-11-20 10:59:49 | NULL | NULL | utf8_general_ci | NULL | | InnoDB free: 9216 kB |
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+----- mysql> show full columns from char_test;
+-------+--------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+-------+--------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| col1 | varchar(300) | utf8_general_ci | YES | | NULL | | select,insert,update,references | |
| col2 | varchar(50) | utf8_general_ci | YES | | NULL | | select,insert,update,references | |
+-------+--------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
mysql> truncate table char_test;
Query OK, 3 rows affected (0.05 sec)

此时再重新交换数据,数据就正确了。

mysql> set names gbk;
Query OK, 0 rows affected (0.00 sec) mysql> select * from char_test;
+--------+------------------+
| col1 | col2 |
+--------+------------------+
| 刘备 | 三国演义中的蜀王 |
| 曹操 | 三国演义中的武王 |
| 诸葛亮 | 三国演义中的军师 |
+--------+------------------+
3 rows in set (0.01 sec)

注意:如果你使用一些客户端工具,比如MySQL-Front,连接数据库时要选择好字符集,如果没有选择默认是数据库设定的字符集,本文中数据库默认字符集是latin1,如果你没有手动选择为utf8,当查询如上实验表是又发生了utf8=>latin1,查询出来的结果肯定是乱码。

5.2 将数据库默认字符设置为utf8

这是一种长远考虑,比较安全,比较适合开发环境的方案,因为随着项目规模的扩大,人员的增退因素,不可能每建一个表都要去考虑字符集因素。但缺点就是它必须重启MySQL服务,并影响系统的运行。
编辑my.ini文件,修改如下的属性值为utf8;

[client]
port=3306
default-character-set=utf8 [mysql]
default-character-set=utf8 # The default character set that will be used when a new schema or table is
# created and no character set is defined
default-character-set=utf8

注意:每个MySQL版本的字符集设置都不一样,详细信息请查阅版本文档。
然后重启MySQL服务;服务启动完成后进一步检查数据库字符集信息;

mysql> show variables like 'character%';
+--------------------------+--------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | D:\develope\MySQL5.0\share\charsets\ |
+--------------------------+--------------------------------------+ mysql> show variables like 'coll%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database | utf8_general_ci |
| collation_server | utf8_general_ci |
+----------------------+-----------------+

都为utf8了,根据上面的分析,如果此时创建表没有知道字符集,那么表和列的字符集都会继承数据库字符集;

drop table char_test;
create table char_test(
col1 varchar(300),
col2 varchar(50)
); mysql> show table status like 'char_test';
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-----
----------------+-------------+------------+-----------------+----------+----------------+----------------------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Crea
te_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-----
----------------+-------------+------------+-----------------+----------+----------------+----------------------+
| char_test | InnoDB | 10 | Compact | 0 | 0 | 16384 | 0 | 0 | 0 | NULL | 2015
-11-20 10:59:49 | NULL | NULL | utf8_general_ci | NULL | | InnoDB free: 9216 kB |
+-----------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-----
----------------+-------------+------------+-----------------+----------+----------------+----------------------+
1 row in set (0.00 sec) mysql> show full columns from char_test;
+-------+--------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+-------+--------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
| col1 | varchar(300) | utf8_general_ci | YES | | NULL | | select,insert,update,references | |
| col2 | varchar(50) | utf8_general_ci | YES | | NULL | | select,insert,update,references | |
+-------+--------------+-----------------+------+-----+---------+-------+---------------------------------+---------+
2 rows in set (0.00 sec)

没错吧!此时再交换数据也不会乱码了。

mysql> select * from char_test;
+--------+------------------+
| col1 | col2 |
+--------+------------------+
| 刘备 | 三国演义中的蜀王 |
| 曹操 | 三国演义中的武王 |
| 诸葛亮 | 三国演义中的军师 |
+--------+------------------+

5.3 创建数据库时明确指定字符集

这种方案适用于早期数据库规划阶段和当数据库需要经常迁移时使用;

create database sydb default character set utf8 collate utf8_general_ci;

mysql> use sydb
Database changed
mysql> show variables like 'character%';
+--------------------------+--------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | D:\develope\MySQL5.0\share\charsets\ |
+--------------------------+--------------------------------------+
8 rows in set (0.00 sec)

6 总结

乱码是数据库和数据交换中常见的问题之一,导致的原因很多,有字符集不一致的、有字符集不兼容的、有转换出错的、有应用程序导致的等;Oracle在创建数据库时使用character set 参数定义数据库的字符集,客户端中使用NLS_LANG变量定义客户端环境的字符集,当客户端和服务端的字符集不一样时,服务端先执行字符集转换,然后在存储数据;MySQL中字符集设置相对比较灵活,可以在数据库层面、数据表层面和数据表列层面设置,大大提高了数据表字符集扩展和管理。虽然每个数据库对字符的处理方式也不尽相同,但总的思想是相同的,字符集也是遵循标准或一定规则的,所以阅读官方文档了解原理和基础知识是一切的开始。

--The end(2015-11-20)

DataStage 九、数据交换到MySQL以及乱码问题的更多相关文章

  1. Mysql导入excel数据,解决某些特殊字符乱码问题

    问题 做项目需要从excel表格导入到mysql的数据库表中,excel表格中的“规格”字段的“×”符号导入数据库表中,会出现部分数据的“×”这个符号会乱码,成“?”的形式. 解决方法 打开excel ...

  2. Atitit.常见软件 数据 交换格式 标准

    Atitit.常见软件 数据 交换格式 标准 1. 常见的数据格式txt ,doc ,pic,music ,vodio1 2. 通用格式json yaml phpstr1 3. 专用格式1 4. 用户 ...

  3. mysql 数据库乱码问题

    mysql 数据库乱码问题,按如下顺序检查,一步一步排除出错位置. 最好全部编码都使用UTF8编码. 网页页面编码方式使用UTF8: <meta http-equiv="Content ...

  4. mysql字符乱码

    解决mysql字符乱码思路: mysql服务器字符集 mysql客户端字符集 系统字符集 生产环境改字符集: 1.导出表结构到 scam.sql文件中 2.更改scam.sql文件中的字符集为想要的字 ...

  5. php大力力 [013节]mySQL数据库乱码问题我还没解决

    <?php echo"测试<br>"; $sql_connection = mysql_connect("localhost","e ...

  6. php mysql 中文乱码解决方法

    本文章向码农们介绍php mysql 中文乱码解决方法,对码农们非常实用,需要的码农可以参考一下. 从MySQL 4.1开始引入多语言的支持,但是用PHP插入的中文会出现乱码.无论用什么编码也不行 解 ...

  7. 已有数据表的Mysql字符编码修改

    Mysql字符集修改应该如何实现呢?下面就为您详细介绍已用数据表的Mysql字符集修改方法,希望对您学习Mysql字符集方面能有所启迪. 环境:在应用开始阶段没有正确的设置字符集,在运行一段时间以后才 ...

  8. windows mysql 中文乱码和中文录入提示太大错误的解决方法

    今天操作mysql的时候很郁闷,因为修改默认字符集搞了半天,终于弄成了(关于如何把windows的默认字符集设置成功,可以参看另一篇博文,最终在mysql中输入show variables like ...

  9. 【PHP】将EXCEL表中的数据轻松导入Mysql数据表

    在网络上有不较多的方法,在此介绍我已经验证的方法. 方法一.利用EXCEL表本身的功能生成SQL代码 ①.先在“phpmyadmin”中建立数据库与表(数据库:excel,数据表:excel01,字段 ...

随机推荐

  1. python入门-变量和简单数据类型

    1 title() 是以首字母大写的方式显示每个单词 lower() 字母小写 upper() 字母大写 2 python使用+号来合并字符串 字符串中使用制表符用\t 字符串中使用换行符\n 用rs ...

  2. CUDA C Programming Guide 在线教程学习笔记 Part 8

    ▶ 线程束表决函数(Warp Vote Functions) ● 用于同一线程束内各线程通信和计算规约指标. // device_functions.h,cc < 9.0 __DEVICE_FU ...

  3. myeclipse2016-ci破解疑难杂症问题整理

    感谢网上的各位大神,在你们的基础,我又整理了下安装成功的心得,破解不成功时一定注意下红色字体内容,避免被坑,都是教训. 试了网上N种破解工具+方法,Myeclipse 2016装了很多遍(本人官网下载 ...

  4. 在Textbox中按回车键后继续获取焦点

    textbox的值为空或没有更改时,按下回车键textbox会失去焦点 此时用textbox1.setfocus不能使textbox1重新获取焦点 Private Sub Textbox1_KeyDo ...

  5. ABAP-BarCode-3-调用第三方控件BarTender实现打印

    1.BarTender软件安装及注册 2.BarTender设置好打印模板 3.ABAP生成TXT文件放置FTP服务器指定文件夹 4.BarTender轮询FTP服务器文件夹中的TXT,并按照模板打印 ...

  6. UI5-文档-4.9-Component Configuration

    在我们介绍了模型-视图-控制器(MVC)概念的所有三个部分之后,现在我们将讨论SAPUI5的另一个重要的结构方面. 在这一步中,我们将把所有UI资产封装在一个独立于索引的组件中.html文件.组件是S ...

  7. mysqldump之不老将

    –add-drop-database 每个数据库创建之前添加drop数据库语句.mysqldump -uroot -p –all-databases –add-drop-database –add-d ...

  8. 英语广播原声听力100篇MP3及听力原文

    =============7.6================ Passage 031- 人工智能对人类的利与弊From a personal assistant, to doing searche ...

  9. Haskell语言学习笔记(46)Parsec(3)

    Applicative Parsing 使用 Applicative 式的 Parser. 包括使用 (<$>), (<*>), (<$), (<*), (*> ...

  10. 团队作业4 Alpha冲刺

    第一天 日期:2018/6/13 1.今日完成任务情况以及遇到的问题 许征航:实现了推荐算法的基础逻辑,并按照模块化的思想对算法进行了分步整理. 遇到的问题:现有条件无法实现协同过滤算法,需要简化模型 ...