`
BingJetMa
  • 浏览: 8351 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Jsp(UTF-8) Sql Server(UCS-2) UNICODE国际化问题

阅读更多
    现在有个项目遇到UTF-8编码问题,JSP(UTF-8)--SQL SERVER 2000 (nchar,nvarchar 内部是UCS-2 编码)请求发送都采用UTF-8,UTF-8和UCS-2是两种不同的UNICODE编码方式,所以这样开发完成的时候,发现UTF-8的页面并不能支持所有的语言输入显示,例如数据库在简体操作系统上安装,简体输入显示没有问题,数据库里存储正常,但是如果是输入繁体字符,韩语日语字符,输入后显示的是乱码,数据库里存储的也是乱码。
    查找资料发现UCS-2是两个字节的UNICODE编码,UTF-8是三个字节的UNICODE编码,如果按照这样的编码流程,页面过来的UTF-8不能自动的转换成UCS-2编码,如果是ASP,可以通过设置ASP页面的CODE PAGE 和IIS 的一些参数解决,但是在JAVA里面这个问题变得棘手,目前我能想到的解决方案有两种:
1 JSP页面采用等价于UCS-2编码,请求发送也采用这种编码,这样前后台统一就可以支持多种语言的输入显示。从目前我从网上找到的资料来看,此路不通。
2 在程序里对nvarchar,nchar字段,做转码操作,入库的时候UTF-8 -> UCS-2,出库的时候
UCS-2 -> UTF-8,但是目前还找不到这样的转码API。
    我做过的其他项目采用ORACLE数据库,它安装的时候就能指定AL32UTF-8,前后台统一,支持多语言很顺畅,没想到SQL SERVER 系列支持UNICODE 居然采用UCS-2编码,大家有什么高见,在目前的数据库环境下,有更好的处理方式吗?
分享到:
评论
6 楼 JamesKing 2007-03-08  
听了搂主的描述,也说一下自己做的一个国际化项目的经验。这个项是使用
架构: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有关这个方面的解释
http://support.microsoft.com/kb/232580/zh-cn
演示网址:http://www.bomege.comhttp://www.bomege.com  留言部分



概要
某些应用程序 (尤其是基于 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。
5 楼 BingJetMa 2006-11-19  
        问题解决了。在INSERT,UPDATE,查询的SQL语句中,凡是nvarchar(),nchar的字段前面加上N,SQL SERVER 就可以自动把页面传过来的UTF-8编码的字串转化成UCS-2,SQL SERVER 所支持的。显示到页面的时候,在UTF-8页面上直接显示数据库里的UCS-2编码的字符串,也没有乱码。
4 楼 BingJetMa 2006-11-17  
together 写道
看起来是你数据库的字符集的问题,
可以查一下类似下面的语句,第一个参数是安装数据库时所选的字符集:
SELECT COLLATIONPROPERTY('Chinese_PRC_Stroke_CI_AI_KS_WS', 'CodePage')
如果返回值不是936,说明不支持GBK。

sqlserver里带N的类型,表示是使用utf-8存储的。
sqlserver7/2k采用ucs-2而没有采用utf-8是有它自己的小99的。不知道2005版如何。


曾想过通过升级数据库的方式解决,我查过资料sql server 2005,依然是ucs-2。
"sqlserver里带N的类型,表示是使用utf-8存储的。" 这句话不太对,带N的类型是指nchar,nvarchar,ntext这些吧,他们代表使用UNICODE存储,但是内部的UNICODE编码是UCS-2,据我所知。

3 楼 together 2006-11-17  
看起来是你数据库的字符集的问题,
可以查一下类似下面的语句,第一个参数是安装数据库时所选的字符集:
SELECT COLLATIONPROPERTY('Chinese_PRC_Stroke_CI_AI_KS_WS', 'CodePage')
如果返回值不是936,说明不支持GBK。

sqlserver里带N的类型,表示是使用utf-8存储的。
sqlserver7/2k采用ucs-2而没有采用utf-8是有它自己的小99的。不知道2005版如何。
2 楼 BingJetMa 2006-11-17  
Readonly 写道
偶们的系统在SQL Server上好像没有遇到这种问题,偶们后台的数据库栏位类型都是varchar,不用nvarchar,前台用UTF-8编码。
你可以贴一些乱码的繁体或者韩日文来么,偶在自己的系统上试试看。

谢谢回复,从GOOGLE 搜来的日文,韩文,你拿来试试,理论上讲用varchar()是不支持UNICODE的,SQL SERVER 支持UNICODE 就是通过nchar, nvarchar,ntext这些数据类型,而不像ORACLE既有unicode编码的数据类型,同时还有unicode编码的数据库,在安装的时候就指定了。
日文:
URLが変更となりました。 2006年4月1日をもちまして、豊田通商株式会社と株式会社トーメンは合併し、URLはhttp://www.toyota-tsusho.comに変更になりました。 豊田通商株式会社のホームページをご覧になられる方は下記よりご覧ください
韩文:我机子上字库没有安装,看到的乱码,拷贝不过来。
繁体中文:
如果利用地表陸地的1%的面積來截取太陽能,再假設太陽能的轉換率是10%的話,其所產生的瓦數,將是相等於我們目前全世界能源消耗量的兩倍。」上述科學研究的精算結果,明確指出發展永續能源的重要性與高度應用價值...    >> 全文

你可以试一下。
1 楼 Readonly 2006-11-17  
偶们的系统在SQL Server上好像没有遇到这种问题,偶们后台的数据库栏位类型都是varchar,不用nvarchar,前台用UTF-8编码。
你可以贴一些乱码的繁体或者韩日文来么,偶在自己的系统上试试看。

相关推荐

    UCS-2转换为utf-8代码

    UCS-2转换为UTF-8代码集完整版 UCS-2(Universal Character Set 2)是一种 Unicode 编码形式,用于表示 Unicode 字符。UTF-8(Unicode Transformation Format 8)是一种 Unicode 编码形式,用于将 Unicode 字符转换...

    UNICODE与UTF-8转换

    4. **解析复杂性**:UTF-8的解析相对较复杂,因为需要识别字节序列以确定字符长度,而UNICODE的解析相对简单,每个字符都有固定的字节数(在UCS-2或UCS-4中)。 **四、UNICODE与UTF-8的转换** 1. **UNICODE到UTF-8...

    UTF-8 GB2312 UCS 码互换

    - 当UCS-2编码的字符位于U+0000到U+007F范围内时,UTF-8编码与UCS-2完全相同。 - 对于UCS-2编码的字符在U+0080到U+007FF范围内的,UTF-8使用两个字节编码。 - U+00800到U+FFFF范围内的UCS-2字符,UTF-8使用三个字节...

    GB13000 UCS-2格式转UTF-8

    身份证读卡器生成的基本信息TEXT文件,由于是采用 GB 13000 的 UCS-2 编码格式,java读取出来是乱码,这个段代码就是解决转码问题的,亲测可用

    多字节与UTF-8、Unicode之间的转换

    3. **Unicode**:Unicode是一种标准,旨在为世界上所有的字符提供统一且唯一的数字表示形式,通常以UCS-2或UCS-4的形式存储,分别使用2个或4个字节表示一个字符。这里我们关注的是UCS-2,即每个字符使用2个字节表示...

    C++ 实现unicode到utf-8的转码

    在C++中,可以使用`wchar_t`数据类型来存储Unicode字符,尤其是在Windows平台上,它通常与UCS-2编码兼容,即每个字符占16位。 UTF-8则是一种变长的字节编码方案,它可以表示Unicode中的所有码点。UTF-8的特点是,...

    ASCII 及UTF-8 与字符互相转换

    UTF-8(UCS Transformation Format - 8 bit),则是一种基于Unicode的多字节编码方式。Unicode 包含了世界上几乎所有的字符集,包括ASCII在内的多种字符集。UTF-8 最大的特点是其编码规则是可变的,它可以使用1到4个...

    C语言字符编码转换UNICODE、GBK、UTF-8互相转换

    在这个主题中,我们将深入探讨如何在C语言中进行UNICODE、GBK和UTF-8之间的转换。 UNICODE,也称为Unicode Transformation Format(UTF),是一种标准的字符编码,旨在表示世界上所有语言的每一个字符。它使用数字...

    UTF-8 编码转换工具

    UTF-8的全称是“8位无符号字符转换格式”(UCS Transformation Format - 8 bit)。每个Unicode字符在UTF-8中可以由1到4个字节表示。简单来说,对于ASCII字符(包括英文、数字和一些特殊符号),UTF-8编码与ASCII...

    SDL_iconv:用于转换字符编码的库。 在单个C文件中。 支持ASCII US-ASCII 8859-1 ISO-8859-1 UTF8 UTF-8 UTF16 UTF-16 UTF16BE UTF-16BE UTF16LE UTF-16LE UTF32 UTF-32 UTF32BE UTF-32BE UTF32LE UTF-32LE UCS2 UCS-2 UCS-2LE UCS- 2BE UCS-2-INTERNAL UCS4 UCS-4 UCS-4LE UCS-4BE UCS-4-INTERNAL

    SDL_iconv 用于转换字符编码的库。... UCS-2-INTERNAL UCS4 UCS-4 UCS-4LE UCS-4BE UCS-4-INTERNAL SDL_iconv.c是一部分。 我做了一些修改以构建没有完整SDL库的SDL_iconv.c。 许可下的许可。

    UTF-8编码转化(Visual Basic)

    Visual Basic中的字符串是Unicode字符串(UCS-2或UTF-16)。如果需要将这些字符串转换为UTF-8,可以使用`Encoding`类的`GetString`和`GetBytes`方法: ```vbnet Dim utf8Bytes As Byte() = System.Text.Encoding....

    字符转码,gb2312 usc2 ,utf-8

    其次,USC2(Unicode,UCS-2)是Unicode标准的一个早期版本,它使用固定宽度的16位编码,可以表示65536个不同的字符,涵盖了大部分世界上常用的语言文字。USC2是Unicode的一种变体,它不包含扩展的辅助平面,因此...

    Unicode字符的UTF-8、UTF-16、UTF-32编码方式[总结].pdf

    Unicode 字符的 UTF-8、UTF-16、UTF-32 编码方式 Unicode 字符集是计算机上使用的一种字符编码,它为每种语言中的每个字符设定了统一并且唯一的二进制代码,以满足跨语言、跨平台进行文本转换、处理的要求。Unicode...

    UTF-8 UNICODE GBK 相互转换C源码

    UTF-8、UNICODE(也称为UCS-2或UTF-16)和GBK是三种常见的字符编码标准,它们在处理多语言文本时各有特点。本文将深入探讨这些编码方式,以及如何在C语言中进行相互转换。 首先,UTF-8是一种变长编码,它使用1到4个...

    Unicode详解(UTF-8,UTF16,UCS)

    Unicode详解(UTF-8,UTF16,UCS)

    用PHP实现UTF-8和Unicode编码转换的技术.pdf

    6. Unicode的UCS-2编码方式 7. PHP语言在UTF-8和Unicode编码转换中的应用 本文档对UTF-8和Unicode的编码特征进行了详细的分析,并使用PHP语言实现了UTF-8和Unicode编码之间的转换函数,从而获得了使用PHP实现UTF-8...

    UNICODE\Unicode,GBK,GB2312,UTF-8概念基础

    UCS-2类似于早期Unicode的16位编码,而UCS-4则提供了更大的编码空间,能够表示Unicode的所有字符。 UTF(Unicode Transformation Format)是一系列将Unicode字符转换为字节序列的编码方式,以便在网络传输、文件...

    VB GB2312 转UTF-8的函数.zip

    3. **转换为Unicode**:将GB2312字符串转换为Unicode(UCS-2)编码,因为UTF-8是基于Unicode的。 4. **编码为UTF-8**:将Unicode字符串编码为UTF-8格式,可以使用VB的内置函数或其他第三方库完成。 5. **写入UTF-8...

    字符编码转换(GB2312,UTF-8,UNICODE)

    2. UTF-8编码:UTF-8是Unicode Transformation Format的缩写,是一种变长的Unicode编码方式。它可以表示Unicode字符集中所有的字符,包括各种语言的特殊字符。UTF-8的最大特点是兼容ASCII编码,前128个字符(0-127)...

    附录A.字符编码_3在LinuxC编程中使用Unicode和UTF-8[总结].pdf

    在Linux C编程中,字符编码主要涉及Unicode和UTF-8标准。Unicode是一个广泛采用的字符集,它包含世界上几乎所有的文字系统,而UTF-8是Unicode的一种编码方式,具有良好的向后兼容性和易于处理的特性。 UTF-8编码在...

Global site tag (gtag.js) - Google Analytics