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. Linux下同一网段内的IP中两台主机通信不经过路由器(ARP)(转)

    答案一:同一网段A与B通信,不需要路由器介入. A直接广播ARP request 到广播域,B处于同一广播域,可以接收到ARP request,B用单播方式直接告诉A自己的MAC B 地址.A收到B的 ...

  2. VS2010 + IDA SDK 搭建IDA Plugin开发环境

    http://www.h4ck.org.cn/2011/11/vs2010-idasdk6-2-ida-plugin-development/ 1. 执行菜单的File->New->Pro ...

  3. change kernel defconfig

    make -C kernel/goldfish O=/media/linux/1/touch/export/phablet-ubuntu-20130618/out/target/product/gen ...

  4. MySQL 自动添加DateTime

    数据库表里有个AddDate字段,DateTime类型,不能为空,添加记录时自动添加当前时间. 以前用MSSQL 在默认值写个 getdate()  就OK! MySQL写这个报错啊,迷糊! 查了一下 ...

  5. u-boot懂你并不难

    转载:http://blog.chinaunix.net/uid-28236237-id-3865045.html u-boot第一阶段分析(一) u-boot 第一阶段分析(二) u-boot 第二 ...

  6. ssh 远程登陆指定端口

    ssh 到指定端口  ssh -p xx user@ip      xx 为 端口号    user为用户名   ip为要登陆的ip SSH 原理及远程登录 http://www.ruanyifeng ...

  7. llvm中如何利用分支概率和基本块频率估计

    1. 背景 llvm自2.9版以后,已经集成了对分支概率和基本块频率的静态分析. 分支概率(branch probability)是指在程序的控制流图中,从控制流从一个基本块A到其任意后继基本块Si的 ...

  8. linux 网络设备驱动

    linux 网络驱动 谨以此文纪念过往的岁月 一.前言在linux中网络驱动也是一个大头,如何去理解网络驱动是作为一个linux驱动工程师必备的技能.不过同样的设备,在不同人的手中会有不同的效果,其原 ...

  9. ASP.NET HTTP404错误怎么办

    如图所示,HTTP404错误. 这是由于没有安装ASP.NET导致的.我们在控制面板->打开或关闭windows功能->Internet信息服务->万维网服务->应用程序开发功 ...

  10. 第一章:走近java-深入理解java虚拟机-读书总结

    java技术体系: 1.java程序设计语言 2.硬件平台上的java虚拟机 3.class文件格式 4.java的API类库 5.第三方的类库 JDK: java语言,虚拟机,java API类库  ...