看了许多网上使用MSSQL Server 2000/2005使用UTF-8造成数据库存储乱码的描述,也说一下自己做的一个国际化项目的经验。
这个项目描述:
架构:VC++的ATL Server进行开发;
页面:web页面是UTF-8编码,CodePage=65001;
应用服务器程序:编译好的dll是Unicode编码;
操作系统:中文Windows 2003 Server;
数据库联接方式:OLEDB
数据库:中文MSSQL Sever2005,显示Codepage=936,
字段都是支持Unicode的nchar,nvarcha,nText;
SELECT COLLATIONPROPERTY('Chinese_PRC_Stroke_CI_AI', 'CodePage')
936
________________________________________________

发现从Web页面提交的数据到数据后查询总是乱码,经过检查,发现保存的数据直接就是是UTF-8编码,其CodePage=65001,而数据默认显示支持的Unicode语言版本Codepage=936(即是简体中文),所以数据查询的就是乱码,想过两种方案:
1,怀疑是数据时UTF-8编码,而SQLServer是UCS-2 版本,相通过UTF-8-〉UCS-2转换,发现还是行不通,仍然乱码,此路不通;
2,搜索了网络发现并没有现成的例子,经过测试中文系统使用Web页面为GB2312编码提交的数据到数据很正常,基于Windows2003是支持Unicode(UCS-2),排除操作系统的问题,这个过程经过分析可以这么理解:936(Web页面编码GB2312)-〉Unicode(应用服务器端)-〉Unicode(数据库OLEDB传输)-〉UCS-2(数据库)-〉自动转化为936(Unicode简体中文语言版本),而使用UTF-8的Web页面这个过程就是:65001(Web页面编码UTF-8)-〉Unicode(应用服务器端)-〉Unicode(数据库OLEDB传输)-〉UCS-2(数据库)-〉自动转化为936(Unicode简体中文语言版本),所以最后的使用数据分析查询器看到的就是乱码,最后确定的方案就是两种手段:一是更改数据查询分析器的Codepage为65001,很显然当前的SQLServer没有这个功能(没找到?知道的告诉我);二是将前端的UTF-8转为GB2312编码,很显然这个最后成功了,这个过程程序还是保留了所有的多语言的特性,一位UTF-8-〉GB2312,这个过程是无损的(新的验证会出现部分方块无法显示),因为是UTF-8->Unicode->GB2312.
总结:
1,MSSQL Server不支持UTF-8(Codepage=65001)直接显示,数据库查询的显示数据使用默认的Codepage,如简体中文版就是936,繁体中文是950,韩文949等,因此从使用的Web页面UTF-8提交的数据自动转换为所用的Codepage显示,因此就是乱码,这个有待MS SQL Server进一步发展,因为现在Oracle和MySQL是可以支持直接UTF-8存储显示,国际化时请先将数据由UTF-8编码转化为MSSQL数据库默认的编码,读写出来这个过程着相反进行转化,这个过程看起来会因为转化过程影响处理速度(抉择于国际化);
2,ASP/ASPX/JSP/PHP使用MSSQL Server编程支持UTF-8都会面临这样的问题,可以看看MSDN有关这个方面的解释
补充:根据测试和MSDN分析,将UTF-8转化为GB2312并不是很好的方案,这样会使包含韩文、阿拉伯文等等,这些都会变成问号,所以整个过程并不是很繁琐,简化一下:

写数据库:浏览器表单提交数据(UTF-8)(ANSI编码)-〉应用服务器端程序(进行UTF-8-〉Unicode)-〉MS SQL Server(自动转化为字符集936编码显示内容,但数据肯定是Unicode方式存储的);
读数据库:MS SQL Server(936 - Unicode)-〉应用服务器端程序(进行Unicode-〉UTF-8)-〉浏览器显示
注意:其他条件设置不变
两个使用的函数:
1,UTF8转化为Unicode,inline为了编译后更快运行,老用到了,返回字符串为了使用链式表达式
inline WCHAR  *UTF8ToUnicode(const char *str) throw()
 {
  int i = MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,-1,NULL,0);        
  WCHAR   *strUnicode=new   WCHAR[i];        
  MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS,str,-1,strUnicode,i);
  return strUnicode;
  delete []strUnicode;
 }
一定要返回WCHAR 或wchar_t类型,否则有些字符就会变成“?”,Unicode(UCS-2)是2个字节宽
2,Unicode转化为UTF8,inline同上意义
inline char *UnicodeToUTF8(const WCHAR* pText) throw()
 {
  int i= WideCharToMultiByte(CP_UTF8,0,pText,-1,NULL,0,NULL,NULL); //输入缓冲区大小是宽字符数        
  char   *strUTF8   =   new   char[i];        
  WideCharToMultiByte(CP_UTF8,0,pText,-1,strUTF8,i,NULL,NULL);
  return strUTF8;
  delete []strUTF8;
 }

 
————————————————————————————————————————————
MSDN参考( http://support.microsoft.com/kb/232580/zh-cn):
概要
某些应用程序 (尤其是基于 Web) 必须处理是用 UTF-8 编码方法编码 Unicode 数据。 SQL Server 7.0 和 SQL Server 2000 使用 Unicode 编码 (UCS-2) 不同和不识别 UTF-8 作为有效字符数据。 本文讨论一些选项用于处理与此情况。
更多信息
可以以许多不同方式进行编码 Unicode 数据。 UCS-2 和 UTF-8 是两种常见方法来存储表示 Unicode 字符位模式。 作为 UCS-2 MicrosoftWindowsNT、 SQLServer、 Java、 COM, 和 SQLServerODBC 驱动程序和 OLEDB 提供所有内部表示 Unicode 数据。

用于使用 SQL Server 7.0 或 SQL Server 2000 作为后端服务器对于应用程序, 发送和接收 Unicode 数据是以 UTF-8 编码选项包括: 1. 如果应用程序使用 Active Server Pages (ASP) 并且您使用 Internet Information Server (IIS) 5.0 和 Microsoft Windows 2000, " < % Session.Codepage=65001 % > " 添加到您的服务器端 ASP 脚本。 这指示 IIS 以转换所有动态生成字符串 (Response.Write) 从 UCS-2 以 UTF-8 它们发送到客户端之前自动示例:。

如果您不想启用会话, 也可以使用服务器端指令 " < > % @ CodePage " = 65001 %。

自动从客户端发送到服务器通过 GET 或 POST 任何 UTF-8 数据还转换为 UCS-2。 Session.Codepage 属性是推荐方法以处理 Web 应用程序中 UTF-8 数据。 IIS 4.0 和 Windows NT 4.0 上没有此 Codepage 设置。 有关其他信息, 请参阅下列 Microsoft 知识库文章:
254313 (http://support.microsoft.com/kb/254313/EN-US/) 错误消息: ActiveServerPages 错误 ASP 0203 ' ' 无效代码
2. 根据应用程序中翻译与 UCS-2 或 UTF-8。 对于该类型转换的示例代码是在 Unicode 联合会的站点位于:

http://www.unicode.org/Public/PROGRAMS/CVTUTF (http://www.unicode.org/Public/PROGRAMS/CVTUTF)
Internet Request For Comments 文档 RFC2279 中可以找到要转换为 UTF-8 UCS-2 算法的高级说明。

在 WindowsNT 或 Windows 2000, 您可能使用 Win 32 函数 MultiByteToWideChar 和 WideCharToMultiByte 来通过传递常量 CP_UTF8 UTF-8 转换与 UCS-2 作为第一个参数对函数 (65001)。
3. 修改应用程序以使用 UCS-2 代替 UTF-8 编码。
4. 使用 BINARY / VARBINARY / IMAGE 列在服务器上存储实际 UTF-8 数据。 SQLServer 上存储 UTF-8 数据意味着您可不使用 SQLServer 来排序或查找数据一样有效字符数据的这些值范围。 类型的列包含 UTF-8 数据不会返回预期结果包括 " ORDERBY ", 更上 - 比操作 < > 并小于 "-" 比 " 比较和内置 SQLServer 字符串处理函数如 SUBSTRING() "。

但是, 相等比较, 工作只要等效字符串比较是在字节级别。 注意: 您如果 UTF-8 数据存储在 SQLServer 应该不使用字符列 (CHAR/NCHAR / VARCHAR 和等等)。 UTF-8 是无效字符数据到 SQLServer, 和通过非字符数据存储在字符列可能遇到问题如以下 Microsoft 知识库文章中讨论问题:
155723 (http://support.microsoft.com/kb/155723/EN-US/) INF: SQLServer 截断的 DBCS 字符串
234748 (http://support.microsoft.com/kb/234748/EN-US/) PRB: SQLServerODBC 驱动程序将语言事件转换为 Unicode
如果考虑此选项, 请记住您将需要执行从 UTF-8 转换为 UCS-2 如 ODBC、 OLEDB、 COM, 此应用程序中如果曾经需要访问 UTF-8 数据从 Web 浏览器 (例如, 从非基于 Web 的 ODBC 应用程序) 以外任何应用程序存储在 SQLServer Win32API 调用、 VB 和 C 运行时字符串处理函数不能使用 UTF-8 数据。 这将是翻译负担移到其他应用程序。
5. 如果要求不包含需要存储数据的语言是无法满足由单个代码页, 组合可能不需要使用 Unicode。
Unicode 支持引入到 SQLServer 以 SQL Server 7.0。 因为 SQL Server 6.5 不支持的 Unicode 数据, 存储仅选项对于 SQL Server 6.5 列于步骤 4 和步骤 5。

国际化使用UTF-8造成数据库MSSQL Server 2000/2005存储乱码的分析相关推荐

  1. Tomcat5+Mssql server 2000数据库连接池配置

    Tomcat相信大家已经很熟悉了,作为一种免费而强大的java web server,得到了很多java爱好者的青睐,最新版本的tomcat5支持servlet2.4和jsp2.0,今天我将采用Tom ...

  2. SQL Server 2000/2005 数据库分页

    有关分页 SQL 的资料很多,有的使用存储过程,有的使用游标.本人不喜欢使用游标,我觉得它耗资.效率低:使用存储过程是个不错的选择,因为存储过程是经过预编译的,执行效率高,也更灵活.先看看单条 SQL ...

  3. 从SQL Server 2000/2005到SQL Server 2008的升级测试

    本文部分内容摘自<SQL Server 2008管理实战>,人民邮电出版社:<深入MSSQL 2008升级和应用程序的兼容性>,IT专家网:<SQL Server 200 ...

  4. SQL Server 2000 + 2005 + 2008 + 2008R2,完全可以共存

    http://www.aspku.com/database/mssql/32484.html 实践证明,SQL Server 2000 + 2005 + 2008,完全可以共存,注意区别 (1)只要实 ...

  5. 实践证明,SQL Server 2000 + 2005 + 2008,完全可以共存

    <!-- google_ad_section_start --> 实践证明,SQL Server 2000 + 2005 + 2008,完全可以共存,注意区别: (1)只要实例名不同即可( ...

  6. Java/JSP中使用JDBC连接SQL Server 2000/2005

    转自:http://hi.baidu.com/huangdonghui/blog/item/87cf4ff47ba653e37609d7e1.html/cmtid/9c82350965721ba22e ...

  7. 推荐优秀的SQL脚本调试工具Embarcadero DBArtisan 可以调试SQL Server 2000/2005 SQL调试工具汇总...

    调试SQL语句是经常会碰到的需求,常常为了查找报表的数据是否正确,SQL脚本为什么取不到预想中的数据,一般都可以通过调试SQL语句来解决问题,找到原因.问题不一定是系统的Bug,可能是设置不正确,可能 ...

  8. SQL server 2000/2005 智能感应插件(菜鸟新手的帮手)

    今天刚刚看到群里有这个软件,就好奇的有道了一下"SQL_Prompt_4.0.3.12",便下载过来试完下:第一次在博客园发帖,因为自己是菜鸟,不知道发什么好. 1.安装开始,点击 ...

  9. Microsoft SQL Server 2000整合规划

    Microsoft SQL Server 2000整合规划 更新日期: 2004年06月24日 SQL Server技术文章 作者:Allan Hirt 投稿人:Tom Davidson和Shaun ...

最新文章

  1. 顺序表-顺序表的基本操作(插入元素+删除元素)
  2. 菜鸟教程python3-Python3 简介
  3. LINQ 101——分组、Set、转换、Element
  4. [HAOI2007]上升序列
  5. DCMTK:用于创建和加载增强型CT对象的测试
  6. linux系统找运行指令,Linux系统常用指令总结
  7. 领航物联网智能操作系统,指令集完成过亿元 A 轮融资
  8. maven插件打包exec_Exec Maven插件–从Maven Build运行Java程序
  9. PHP 抽象工厂模式(Kit模式)
  10. 个人作业3------个人总结(alpha阶段)
  11. 集群、分布式架构与SOA架构
  12. win8/8.1改win7原版系统全部教程之先把驱动精灵万能网卡版存到U盘(2)
  13. 新浪微博指数查询API接口文档
  14. 24AA512/24LC512/24FC512系列器件中文翻译
  15. Java制作推箱子小游戏
  16. 云服务器系列2-frp-云服务器内网穿透windows远程控制实践
  17. @vue/composition-api/dist/vue-composition-api.mjs in ./node_modules/vue-demi/lib/index.mjs 报错
  18. 龙ol服务器维护补偿boss,《龙OL》12月17日更新公告
  19. 应用宝ysdk微信二维码扫码登录没有回调问题
  20. 微信小程序实现分页加载,触底加载下一页,滚动加载

热门文章

  1. 运维堡垒机是什么?有什么作用?
  2. 华为mates更新鸿蒙,华为鸿蒙OS 2.0开发者Beta招募新增设备:Mate X2、Mate 40等...
  3. 嵌入式软考备考_6 嵌入式程序设计
  4. 深入理解TDNN(Time Delay Neural Network)——兼谈x-vector网络结构
  5. [附源码]计算机毕业设计JAVA宠物之家管理系统
  6. 苹果电脑如何把Windows系统安装到U盘?
  7. 【大疆面试】7.24
  8. 路由器单臂路由配置------配置子接口是配置单臂路由的关键
  9. TuckERT/TuckERTNT
  10. VB6 Getobject(,“excel.application“) 错误429 ActiveX 部件无法创建对象