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;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值