c#+mysql 中文乱码

遇到一个奇怪的问题,C#读取mysql中文正常,写入时发生乱码

网上查阅原因,发现如下信息

---------------------------------------------------------------------

一、错误读出

现象:一个已经存在数据的MySQL数据库,该数据库的数据用系统中其它软件、网页查看均正常,使用MySQLcc之类的客户端查看也正常,可是在新写的网页中总是显示乱码。

分析:其它系统都可以正常查看数据,说明数据本身是没有问题的。在网页中显示乱码,一定是网页的编码字符集和获取到的数据的编码字符集不一至。比如数据库的字符集是UTF8的,而网页的字符集是gb2312的,那么网页就会把UTF8编码的字体串当作gb2312的来处理,结果产生乱码。

解决办法:在连接数据库时,设定连接字符集,使连接字符集和当前网页或客户端程序使用的字符集一致。可以使用MySQL的Set Names指令设定连接字符集。假设网页的字体集为gb2312。在连接MySQL后,在连接上执行如下SQL语句:

Set Names ‘gb2312’

在以后所有这个连接上的查询,MySQL都会自动把数据库中的数据转换成gb2312编码格式传过来。

二、错误写入

现象:一个网页或程序向一个MySQL数据库中写数据,写完后,这个网页或程序自己可以正常读取数据,而从其它客户端或网页中读取数据都是乱码。

分析:其它的正常的客户端出现乱码,说明数据库中的字符编码不对。写数据的那个网页能正常读取,是因为写和读都用了错误的编码格式,将错就错,反而能读出正确的数据了。比如数据库中设定的字符集为UTF8,而网页使用gb2312编码执行了插入数据的SQL,那么MySQL就会把这些gb2312的编码当成是UTF8的编码写进数据库。当其它客户端访问数据时,会按系统的设定,以UTF8 格式读取数据,而数据其实是使用gb2312编码的,结果就出现了乱码。只有写数据的那个网页会把这些数据当成gb2312的,也只有那个网页能正常显示数据。

解决办法:同第一条,即:使用Set Names指令设定连接字符集。

在设定了连接字符体的连接上执行数据操作,所有的数据都将被MySQL自动、正确地转换为数据库中设定的编码格式保存。

通过以上两点,我们可以看到,只要在连接MySQL时,正确地设定了字符集,无论数据库本身是使用什么格式编码的,都能得到正确的结果。也许有人会以为写数据时设定的字符集必需和读数据时一致,事实上完全没有必要。程序所要做的只是告诉 MySQL,目前操作MySQL使用的是什么字符集即可。因为MySQL会自动完成如下的转换工作:

写数据库时用的字符集-->存诸数据的字符集-->读取数据的字符集。

笔者以为MySQL对多语言字符集的处理是非常优秀的,并且每次建立到MySQL的连接都会立刻使用Set Names设定字符集,然而最近还是出现了一回乱码,如下面所述。

三、无知的程序包

现象:使用C#编程,使用MySQL提供的连接程序库包访问数据库,使用 MySqlConnection类连接数据库,连接之后立刻调用Set Names设定连接字符串,然后使用MySqlCommand类执行SQL,并使用MySqlDataReader读取数查询结果。然而,当我调用 MySqlDataReader的成员方法GetString获取数据的时候,发现得到的全是乱码。百思不得其解。

分析:经仔细检查,确信问题没有出在MySQL连接上面,这时我想到了C#中对 string类型的处理。在C#中字符串和C/C++中有很大不同。在C/C++中一个字符就是一个字节,而在C#中,按不同的编码格式,一个字符也可以是多个字节的。比如”啊”就是一个字符,如果一个字符串s=”啊”; 那么s的Length属性为1,而不是C/C++中的2。我想MySQL程序包也许并不知道连接上传过来的字符是什么编码的,它因为无知,所以只是按单字节字符把这些数据组织成一个string,这个生成的string就是我得到的乱码。事实上也的确是这样。

解决办法:把这些数据重新组织起来,然后使用正确的编码方法重新生成string。C#中System.Text包内的Encoding类提供了字符集的编/解码方法。

1)首先还是设定连接字符集,以确认收到的字符的编码方式。
2)把GetString得到的字符串转换到byte数组中。
3)使用Systec.Text.Encoding包中相应字符集的解码方法GetString得到新的字符串。

为了通用性,我们使用System.Text.Encoding的默认字符集。连接数据库时,设置数据库连接字符集使用的SQL指令strSetCharset为如下值:
string strSetCharset = “Set Names ” + System. Text. Encoding .Default. HeaderName;

在获取数据时,使用下面的函数得到真正的字符串:

private string DBStringToNormal(string dbStr)
       {
         byte[] str = new byte[dbStr.Length];
         for (int i = 0; i < dbStr.Length; ++i)
            str[i] = (byte)(dbStr[i]);
    return System.Text.Encoding.Default.GetString(str, 0, dbStr.Length);
}
-----------------------------------------------------------------------------------------------------------------

看到这个文章受到启发,重要的一句是:

通过以上两点,我们可以看到,只要在连接MySQL时,正确地设定了字符集,无论数据库本身是使用什么格式编码的,都能得到正确的结果。也许有人会以为写数据时设定的字符集必需和读数据时一致,事实上完全没有必要。程序所要做的只是告诉 MySQL,目前操作MySQL使用的是什么字符集即可。因为MySQL会自动完成如下的转换工作:

写数据库时用的字符集-->存诸数据的字符集-->读取数据的字符集。

由此想我的问题可能是写入时声明的我的字符编码与我实际的不符,C#中字符默认编码为GB2312,于是程序改动如下:

1:在链接字符加入字符编码声明

<add key="mysqlconstr" value="UserId=root;Allow Zero Datetime=true;Charset=gb2312;Host=125.*.*.*;Database=dbname;Password=123456"/>

向mysql说明我的字符编码是gb2312, 不要搞错

2:在数据库类中每一插入数据语句前加入编码声明

cmd = new MySqlCommand("set names gb2312;"+sql,conn);
    cmd.ExecuteNonQuery();

期待已久的中文终于顺利写入了!

c#+mysql 中文乱码的更多相关文章

  1. 解决springmvc+mybatis+mysql中文乱码问题【转】

    这篇文章主要介绍了解决java中springmvc+mybatis+mysql中文乱码问题的相关资料,需要的朋友可以参考下 近日使用ajax请求springmvc后台查询mysql数据库,页面显示中文 ...

  2. 总结--解决 mysql 中文乱码

    首先分析一下导致mysql 中文乱码的原因: 1.建表时使用了latin 编码 2.连接数据库的编码没有指定 3.写入时就已经乱码(这种情况需要自己检查源数据了) 解决方法总结: 1.创建库时指定编码 ...

  3. Servlet、MySQL中文乱码

    1.Servlet中文乱码: 在doPost或doGet方法里,加上以下两行即可: response.setContentType("text/html;charset=UTF-8" ...

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

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

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

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

  6. MySQL编程(0) - Mysql中文乱码问题解决方案

    MySQL 5.6 for Windows 解压缩版配置安装: http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345bf0.html MySQL ...

  7. MySQL及navicat for mysql中文乱码

    转载自:https://www.cnblogs.com/mufire/p/6697994.html 修改完之后记着重启mysql服务,在服务里边重启,即可生效! 全部使用utf8编码 MySQL中文乱 ...

  8. 通过msyql proxy链接mysql中文乱码及session问题

    1.session问题 问题前提:一台机数据库为两个实例,通过不同的socket监听不同端口对外提供服务.不同的站点都访问同一个VIP不同的端口进行访问数据库. 故障现象:一旦有一个站点先用了这个vi ...

  9. 可遇不可求的Question之导入mysql中文乱码解决方法篇

    可遇不可求的Question之导入mysql中文乱码解决方法篇 先 set names utf8;然后 source c:\1.sql ?

  10. PHP彻底解决mysql中文乱码

    彻底解决mysql中文乱码 mysql是我们项目中非经常常使用的数据型数据库. 可是由于我们须要在数据库保存中文字符,所以经常遇到数据库乱码情况.以下就来介绍一下怎样彻底解决数据库中文乱码情况. 数据 ...

随机推荐

  1. busdog is a filter driver for MS Windows (XP and above) to sniff USB traffic.

    https://code.google.com/p/busdog/ busdog is a filter driver for MS Windows (XP and above) to sniff U ...

  2. Spring过滤器组件自动扫描

    在这个Spring自动组件扫描的教程,您已经了解如何使Spring自动扫描您的组件.在这篇文章中,我们将展示如何使用组件过滤器自动扫描过程. 1.过滤组件 - 包含 参见下面的例子中使用Spring  ...

  3. Spring使用@Required注解依赖检查

    Spring依赖检查 bean 配置文件用于确定的特定类型(基本,集合或对象)的所有属性被设置.在大多数情况下,你只需要确保特定属性已经设置但不是所有属性.. 对于这种情况,你需要 @Required ...

  4. Fiddler2 中文手册

    原文:http://blog.sina.com.cn/s/blog_66a13b8f0100vgfi.html 最近一阵研究 Fiddler2 的使用来着,一开始看起来有点找不着北,索性就根据官网资料 ...

  5. OpenERP实施记录(12):付款处理

    本文是<OpenERP实施记录>系列文章的一部分. 1. 在前面的文章中,采购订单确认时自动生成了供应商发票,可以在 会计 > 供应商列表 > 供应商发票 查询,状态为&quo ...

  6. [转载] 无所不能的“蚂蚁”--Ant

    说他无所不能,好像有点夸张,但是用过Ant之后,感觉真的是只有想不到没有作不到.Ant,原作者选择他作为软件名字的意思是指"令一个简洁的工具"(Another Neat Tool) ...

  7. javascript无缝滚动原理

    相比之下,无缝拼接能避免切换时出现空白,使用户体验更好! 无缝滚动原理: 制作一个双胞胎,内容跟主体内容一致,样式一致,如果横向排列则并排,当切换的时候,就可以弥补主体空白的地方,其他按普通循环操作即 ...

  8. jQuery EasyUI API 中文文档 - Panel面板

    <html> <head> <title>布局管理器--控制面板</title> <script src="jquery-easyui/ ...

  9. C99规范

    . 增加restrict指针 C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象.restrict指针指针主 ...

  10. Meanshift,聚类算法(转)

    原帖地址:http://www.cnblogs.com/liqizhou/archive/2012/05/12/2497220.html   记得刚读研究生的时候,学习的第一个算法就是meanshif ...