otl通过odbc连接mysql中文乱码测试
问题描述:
问题一直出现的很怪异,通过例子来阐述。
环境:
mysql-5.1.62-win32 + otl + mysql-connector-odbc-5.1.11-win32 + navicat101_mysql_en
建立一张测试表:
CREATE TABLE `t_cntest` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `value` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
t_cntest表只有两个字段,一个是递增的ID号,一个是可以保存中文的value;
当用otl开始往该数据表里面插入值时,问题出现了
1. insert into t_cntest(value) values ('中文');(下文称为%s方式)用navicat显示正常,但是再通过
select value from t_cntest读出来,却是乱码;
2. insert into t_cntest(value) values (:f1<char[64]>); (下文称为流方式) <p><span style="color:gray;">stream<<</span><span style="color:gray;">”</span><span style="color:gray;">中文</span><span style="color:gray;">”</span><span style="color:gray;">;</span></p>
用otl的这中流方式方式写入mysql,再用流方式来读取
select value from t_cntest where value=:f1<char[64]>
读出来中文正常,但是navicat查看却是乱码;
3、网络解决办法
网上十有八九都是:set names utf8云云,但是otl不允许这么做,执行异常;
于是一个一个的来设置吧:
Set character_set_client=’utf8’
Set character_set_connection=’utf8’
Set character_set_results=’utf8’
可能我人品不好,还是NO!
==========================================================================================
一顿摸索测试,后来觉得,应该是odbc在搞鬼,于是在数据源增加指定的数据源,便OK了。
在odbc数据源管理器中,用户DSN里面,添加一个数据源,名字任意,如下图:
在添加过程中,或者添加完再配置,点开“connection”扩展栏,选择字符集gbk。
然后就是要在代码中指定这个配置好的数据源了,这很重要。
可能你会发现,如果不增加DSN,默认是没有这个DSN的,那么OTL用的是哪里的DSN?谁能解释一下。。。。。。?
以前的登陆连接串是这样的:
Driver={MySQL ODBC 5.1 Driver};Server=localhost;DataBase=test_cn;Uid=root;Pwd=123456
现在必须是:
DSN=dsn_test_cn;Driver={MySQL ODBC 5.1 Driver};Server=localhost;DataBase=test_cn;Uid=root;Pwd=123456
对,就是多加了一个DSN=...,名字是你刚刚自己创建的。
享用结果:
这样怎么写,怎么读都OK了!!!
再次,用%s方式或者流方式写入,navicat都显示正常用%s方式或者流方式写入,打印也都正常
走不完的路:
有个疑问,能否在代码中配置这个DSN的字符集呢?否则每次换一台电脑,都必须配置一次数据源,多麻烦。。。
附件:
我的mysql测试字符集环境:
Mysql字符环境: mysql> show variables like 'char%'; +--------------------------+---------------------------------------------------------+ | Variable_name | Value | +--------------------------+---------------------------------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | gbk | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | gbk | | character_set_system | utf8 | | character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.1\share\charsets\ | +--------------------------+---------------------------------------------------------+ 8 rows in set mysql> show variables like 'coll%'; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | utf8_general_ci | | collation_database | gbk_chinese_ci | | collation_server | gbk_chinese_ci | +----------------------+-----------------+ 3 rows in set
测试例子程序(主要是main以内的测试代码,头文件和宏定义看自己的otl情况而定):
// Test_Otl.cpp : 定义控制台应用程序的入口点。 // #define OTL_ODBC_MSSQL_2005 // Compile OTL 4/ODBC, MS SQL 2005 #define OTL_ODBC // Compile OTL 4/ODBC. Uncomment this when used with MS SQL 7.0/ 2000 #define OTL_EXTENDED_EXCEPTION // Enable extended field in otl_exception #define OTL_ORA11G #include "stdafx.h" #include "otlv4.h" #include <time.h> #include <iostream> using namespace std; #pragma comment(lib , "oci.lib") int _tmain(int argc, _TCHAR* argv[]) { //连接mysql string strConnect; strConnect += "DSN="; strConnect += "dsn_test_cn;"; strConnect += "Driver="; strConnect += "{MySQL ODBC 5.1 Driver}"; strConnect += ";Server="; strConnect += "localhost"; strConnect += ";DataBase="; strConnect += "test_cn"; strConnect += ";Uid="; strConnect += "root"; strConnect += ";Pwd="; strConnect += "123456"; //DSN=dsn_test_cn;Driver={MySQL ODBC 5.1 Driver};Server=localhost;DataBase=test_cn;Uid=root;Pwd=123456 odbc::otl_connect odbc_con; try{ int nRet = odbc::otl_connect::otl_initialize(true); // initialize oracle environment odbc_con.rlogon(strConnect.c_str()); if (!odbc_con.connected) { printf("未连接\n"); return -1; } long lRet = -1; #define INSERT 0 #define SELECT 1 char szSql[1024]={0}; odbc::otl_stream stream; string str1 = "this is 百分号s写入"; string str2 = "this is 流方式写入"; #if INSERT //插入中文记录 %s方式 sprintf_s(szSql, sizeof(szSql), "insert into t_cntest(value) values ('%s')",str1.c_str()); stream.open(1,szSql,odbc_con); stream.close(); //插入中文记录 流方式 sprintf_s(szSql, sizeof(szSql), "insert into t_cntest(value) values (:f1<char[64]>)"); stream.open(1,szSql,odbc_con); stream<<str2.c_str(); stream.close(); #endif #if SELECT //查询数据 //sprintf_s(szSql, sizeof(szSql), "select value from t_cntest");//查全部 //%s方式读 //sprintf_s(szSql, sizeof(szSql), "select value from t_cntest where value='%s'",str1.c_str());//查str1 //sprintf_s(szSql, sizeof(szSql), "select value from t_cntest where value='%s'",str2.c_str());////查str2 //stream.open(1,szSql,odbc_con); //流方式读 sprintf_s(szSql, sizeof(szSql), "select value from t_cntest where value=:f1<char[64]>"); stream.open(1,szSql,odbc_con); //stream<<str1.c_str(); stream<<str2.c_str(); //结果展示 char szValue[64]={0}; while (!stream.eof()) { stream>>szValue; printf("select value=%s\n",szValue); } stream.close(); #endif //注销登录 odbc_con.commit(); odbc_con.logoff(); } catch(odbc::otl_exception &e) { } system("pause"); return 0; }
posted on 2017-10-12 21:27 zhuxian2009 阅读(593) 评论(0) 编辑 收藏 举报