`
yangzb
  • 浏览: 3501973 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用AL32UTF8字符集遇到的问题

阅读更多

: 使用AL32UTF8字符集遇到的问题

离线 Arrayxipipku
中级会员



精华贴数 0
个人空间 0
技术积分 624 (3067)
社区积分 2 (24995)
注册日期 2004-5-11
论坛徽章:2
授权会员 开发板块每日发贴之星        
           
发表于 2005-4-13 17:16 
使用AL32UTF8字符集遇到的问题

客户端的字符集也设置为AL32UTF8,执行语句时出现一下问题:

SQL>  update t_port_permission set permission_name='删除入库' where permission_name='123';
ERROR:
ORA-01756: quoted string not properly terminated


SQL> update t_port_permission set permission_name='删除管理员' where permission_name='123';

1 row updated.

SQL> commit;

Commit complete.

SQL> update t_port_permission set permission_name='管理员管理' where permission_name='234';
ERROR:
ORA-01756: quoted string not properly terminated
SQL> update t_port_permission set permission_name='操作员' where permission_name='234';

1 row updated.

SQL> commit;

有写中文组合能进去,有些不可以,将sql写出脚本执行也是一样的效果,怎么去解决这个问题,最好是能告诉一下分析的思路。


只看该作者    顶部
离线 bachang
初级会员



精华贴数 0
个人空间 0
技术积分 48 (28339)
社区积分 0 (62519)
注册日期 2002-8-13
论坛徽章:0
           
           
发表于 2005-4-13 17:28 
你可以設定為AMERICAN_AMERICA.ZHS16GBK試試


只看该作者    顶部
离线 xipipku
中级会员



精华贴数 0
个人空间 0
技术积分 624 (3067)
社区积分 2 (24995)
注册日期 2004-5-11
论坛徽章:2
授权会员 开发板块每日发贴之星        
           
发表于 2005-4-13 17:57 
使用AMERICAN_AMERICA.ZHS16GBK进行读取是没问题,但我主要是想知道为什么,我分析了一下在ZHS16GBK环境中数据库存储的信息情况:
SQL> insert into test values('删除');

1 row created.

SQL> select dump(name) from test;

DUMP(NAME)
--------------------------------------------------------------------------------
Typ=1 Len=6: 229,136,160,233,153,164

可以看出在数据库中每个汉字的存储是三个字节,编码方式实际上是UTF-8的编码。

再看一下AL32UTF8字符集时候的情况:
SQL> insert into test values('删除');

1 row created.

SQL> select dump(name) from test;

DUMP(NAME)
--------------------------------------------------------------------------------
Typ=1 Len=4: 201,190,179,253
可以看到,每个汉字的编码实际上是按照gb2312进行的编码

与我一开始的想法正好想反,谁能帮我分析一下这整个过程,从客户端录入到存储再到读出。


只看该作者    顶部
离线 sydongsun
高级会员



精华贴数 0
个人空间 0
技术积分 4101 (353)
社区积分 95 (3561)
注册日期 2003-7-5
论坛徽章:10
会员2007贡献徽章 会员2006贡献徽章 2008年新春纪念徽章 ITPUB新首页上线纪念徽章 ERP板块每日发贴之星 ERP板块每日发贴之星
数据库板块每日发贴之星 ERP板块每日发贴之星 ERP板块每日发贴之星 操作系统板块每日发贴之星    
发表于 2005-4-13 18:12 
几乎没有将客户端设置为AMERICAN_AMERICA.AL32UTF8的,在正常情况下,这个参数中的是字符集要反映你的操作系统所采用的字符集的。windows下不知道是否有采用这种AL32UTF8的语言设置? 我估计应该没有。

你需要的详细说一说,可以参考:
http://www.askguoyu.com/db/charset.htm

其实是一个特别好的培训课程。我不知道在参加某些培训课程的时候,是否会讲述的这么详细?一般很少。都是让大家看书的来深入学习这部分内容的。


__________________
===============================
= 欢迎访问我的个人网站:分别选择兴趣主题:
= 开始销售:SAPBW顾问培训课程   
= 销售:Oracle备份和恢复详尽的教程   
|| 软件配置管理 || Lotus Domino   || 数据库技术 ||  
=  = 部分在线教程信息:
= DB2基础入门和备份    || SAP ALE || APAP程序设计 || SAP系统管理 || SAP权限控制
===============================
只看该作者    顶部
离线 jeffli73
侠之大者


精华贴数 2
个人空间 0
技术积分 10578 (113)
社区积分 21 (7384)
注册日期 2002-6-17
论坛徽章:1
授权会员          
           
发表于 2005-4-13 18:24 
请参考


__________________
安能摧眉折腰事权贵,使我不得开心颜天生我才必有用,千金散尽还复来个人BLOG: http://blog.china-pub.com/blog.asp?name=jefflee包括数据库、软件工程、电信及其它方面的个人感悟,如有兴趣,欢迎访问
只看该作者    顶部
离线 xipipku
中级会员



精华贴数 0
个人空间 0
技术积分 624 (3067)
社区积分 2 (24995)
注册日期 2004-5-11
论坛徽章:2
授权会员 开发板块每日发贴之星        
           
发表于 2005-4-14 10:27 
谢谢 sydongsun 和 jeffli73 的帮助,看了相关帖子,对字符集的理解更深刻了,分析一下我出现的问题,
如果客户端和服务器端都是 AL32UTF8的情况,Oracle检查数据库与客户端的字符集设置是同样的,那么数据在客户与数据库之间的存取过程中将不发生任何转换,所有录入到数 据库中的内容实际上是以gbk编码的,在读取的时候由于客户端和服务器端的字符集一致,所有也不会发生字符集的转换,读出的也是gbk的编码。当客户端设 置的字符集是gbk时, 服务器端判断出两边的字符集不符合,所以会将gbk编码转换成utf-8的编码,同时客户端在读取时,会将utf-8的编码转成gbk编码,这样就保证了 中文输入的正确性。
但是我还是没有分析出为什么在客户端和服务器端都为utf-8时为什么会出现
SQL> select dump('管') from dual;
ERROR:
ORA-01756: quoted string not properly terminated

管的汉字编码是
SQL>SQL> select dump('管') from dual;

DUMP('管')
---------------------
Typ=96 Len=2: 185,220


  ' 的编码是39
在解析的时候为什么会出现'呢?


只看该作者    顶部
离线 sydongsun
高级会员



精华贴数 0
个人空间 0
技术积分 4101 (353)
社区积分 95 (3561)
注册日期 2003-7-5
论坛徽章:10
会员2007贡献徽章 会员2006贡献徽章 2008年新春纪念徽章 ITPUB新首页上线纪念徽章 ERP板块每日发贴之星 ERP板块每日发贴之星
数据库板块每日发贴之星 ERP板块每日发贴之星 ERP板块每日发贴之星 操作系统板块每日发贴之星    
发表于 2005-4-14 11:24 
问题在于:
在客户端和服务器端都为utf-8时,假如你正确存入了汉字信息到数据库服务器上,一般来说汉字的UTF8的编码为三个byte。然后你的客户端也是 utf-8, 那么不经过转换就会通过select 显示,比如“管”的假定的信息是185,220,148 (这里是随意写的),但是你的客户端是否具有这样的字符集呢?一般的Windows操作系统是不会让你选择一种UTF8的字符集的,要么是GBK的简体中 文,要么是美国标准英文,后者是windows系统的标准英文,或者是日文操作系统等,没有一种使用UTF8的显示和输入的操作系统。

事实上,Unicode编码主要是一种信息存储的编码方式。可以支持世界上主要的语言的所有字符都能够用一个唯一的编码值在表示和存储。在信息来显示和输 入的时候,大家都还是使用各自的语言的。比如,一个网络在线商店,可以接受,中文的,泰问,日本专有字符,蒙古文的操作系统的输入的内容,同一转换成 UTF8存储到数据中,然后各个操作系统要进行读取的时候,也分别按照UTF8 到各自的操作系统编码转换进行读取。现在全世界还没有一种可以同时使用包含所有主要语言的操作系统,在Windows平台可以通过国家语言设置来进行转换 (但是要么是选择中文版,好么是选择英文版,要么是蒙古文....  ,不能同时选择所有,否则我们的键盘的键格数量要大大增加),所以,没有将客户端设 置为语言选择为UTF8的操作系统。

你需要仔细理解,我的回答并不是非常清楚。

另外,从你 select dump('管') from dual, 实际上表示的是你操作系统当前所使用的语言编码是GBT的,应为只有2个byte. 所以你的AMERICAN_AMERICA.ZHS16GBK 只能选择ZHS16GBK, 永远不要选择为UTF8, 只有你想执行数据库的字符集转换的时候,你在exp和imp的时候,为了exp数据的字符集变化,你可以临时让客户端和数据库段一致。 但是几乎很少有从utf8这种unicode转换到非unicode的工作场景的。


__________________
===============================
= 欢迎访问我的个人网站:分别选择兴趣主题:
= 开始销售:SAPBW顾问培训课程   
= 销售:Oracle备份和恢复详尽的教程   
|| 软件配置管理 || Lotus Domino   || 数据库技术 ||  
=  = 部分在线教程信息:
= DB2基础入门和备份    || SAP ALE || APAP程序设计 || SAP系统管理 || SAP权限控制
===============================
只看该作者    顶部
离线 xipipku
中级会员



精华贴数 0
个人空间 0
技术积分 624 (3067)
社区积分 2 (24995)
注册日期 2004-5-11
论坛徽章:2
授权会员 开发板块每日发贴之星        
           
发表于 2005-4-15 10:49 


QUOTE:
最初由 sydongsun 发布
问题在于:
在客户端和服务器端都为utf-8时,假如你正确存入了汉字信息到数据库服务器上,一般来说汉字的UTF8的编码为三个byte。然后你的客户端也是 utf-8, 那么不经过转换就会通过select 显示,比如“管”的假定的信息是185,220,148 (这里是随意写的),但是你的客户端是否具有这样的字符集呢?一般的Windows操作系统是不会让你选择一种UTF8的字符集的,要么是GBK的简体中 文,要么是美国标准英文,后者是windows系统的标准英文,或者是日文操作系统等,没有一种使用UTF8的显示和输入的操作系统。

事实上,Unicode编码主要是一种信息存储的编码方式。可以支持世界上主要的语言的所有字符都能够用一个唯一的编码值在表示和存储。在信息来显示和输 入的时候,大家都还是使用各自的语言的。比如,一个网络在线商店,可以接受,中文的,泰问,日本专有字符,蒙古文的操作系统的输入的内容,同一转换成 UTF8存储到数据中,然后各个操作系统要进行读取的时候,也分别按照UTF8 到各自的操作系统编码转换进行读取。现在全世界还没有一种可以同时使用包含所有主要语言的操作系统,在Windows平台可以通过国家语言设置来进行转换 (但是要么是选择中文版,好么是选择英文版,要么是蒙古文....  ,不能同时选择所有,否则我们的键盘的键格数量要大大增加),所以,没有将客户端设 置为语言选择为UTF8的操作系统。

你需要仔细理解,我的回答并不是非常清楚。

另外,从你 select dump('管') from dual, 实际上表示的是你操作系统当前所使用的语言编码是GBT的,应为只有2个byte. 所以你的AMERICAN_AMERICA.ZHS16GBK 只能选择ZHS16GBK, 永远不要选择为UTF8, 只有你想执行数据库的字符集转换的时候,你在exp和imp的时候,为了exp数据的字符集变化,你可以临时让客户端和数据库段一致。 但是几乎很少有从utf8这种unicode转换到非unicode的工作场景的。


谢 谢你的回答,实际上怎么使用字符集这个问题我很清楚了,我只是想解释一下出现的现象而已,想通过这方面的研究加深对字符集编码的理解。事实上UFT8的两 字节编码为:110***** 10******   第一个字节的110和第二个字节的10为标志位。三个字节的编码为:1110***** 10****** 10******,第一个字节的1110和第二、三个字节的10都是标志位,剩下的空间正好可以表示汉字。
我们再来看一下测试的数据情况:
在utf-8的环境下执行:

SQL> select dump('管',16) from dual;
ERROR:
ORA-01756: quoted string not properly terminated
管的16机制编码为:
而‘管’字的GBk编码是b9 dc ,事实上不在utf8二字节和三字节的编码范围中,它是以单字节编码的读取方式,写读b9, 然后再读dc,读到dc的时候,由utf-8的编码规则可以知道是二字节编码的,所以他会把后面的'当成二字节编码的一部分,所以就会出现'缺失的现象

SQL> select dump('管1',16) from dual;

DUMP('管1',16)
----------------------
Typ=96 Len=3: b9,dc,31
读的时候  b9  (dc,31)同样的测试可以看到:
SQL> select dump('理12',16) from dual;

DUMP('理12',16)
-------------------------
Typ=96 Len=4: c0,ed,31,32
读取的顺序 c0 (ed 31 32)

SQL> select dump('理1',16) from dual;
ERROR:
ORA-01756: quoted string not properly terminated
    读取的顺序 c0 (ed 31 39),把引号吃掉了
SQL> select dump('理发',16) from dual;

DUMP('理发',16)
-------------------------
Typ=96 Len=4: c0,ed,b7,a2
          读取的顺序为c0 (ed,b7, a2)

通过上面的分析就很容易知道为什么会出现引号缺省的问题了。通过这个问题的解决对字符集的理解大大加深了,谢谢各位的帮助。


只看该作者    顶部
离线 bachang
初级会员



精华贴数 0
个人空间 0
技术积分 48 (28339)
社区积分 0 (62519)
注册日期 2002-8-13
论坛徽章:0
           
           
发表于 2005-4-15 11:30 
以Oracle文件说法~~~档Client and Server使用同一NLS_LANG时~~~Oracle并不会自动帮你进行资料的转换动作~~~所以会以Client的OS的Language来决 定~~~如是GBK就是GBK码~~~所以当资料库为UTF8时就需以Client的OS的Language不同而有不同的设定


只看该作者    顶部
离线 sydongsun
高级会员



精华贴数 0
个人空间 0
技术积分 4101 (353)
社区积分 95 (3561)
注册日期 2003-7-5
论坛徽章:10
会员2007贡献徽章 会员2006贡献徽章 2008年新春纪念徽章 ITPUB新首页上线纪念徽章 ERP板块每日发贴之星 ERP板块每日发贴之星
数据库板块每日发贴之星 ERP板块每日发贴之星 ERP板块每日发贴之星 操作系统板块每日发贴之星    
发表于 2005-4-15 11:38 


QUOTE:
最初由 xipipku 发布

谢谢你的回答,实际上怎么使用字符集这个问题我很清楚了,我只是想解释一下出现的现象而已,想通过这方面的研究加深对字符集编码的理解。事实上UFT8的 两字节编码为:110***** 10******   第一个字节的110和第二个字节的10为标志位。三个字节的编码为:1110***** 10****** 10******,第一个字节的1110和第二、三个字节的10都是标志位,剩下的空间正好可以表示汉字。
我们再来看一下测试的数据情况:
在utf-8的环境下执行:

SQL> select dump('管',16) from dual;
ERROR:
ORA-01756: quoted string not properly terminated
管的16机制编码为:
而‘管’字的GBk编码是b9 dc ,事实上不在utf8二字节和三字节的编码范围中,它是以单字节编码的读取方式,写读b9, 然后再读dc,读到dc的时候,由utf-8的编码规则可以知道是二字节编码的,所以他会把后面的'当成二字节编码的一部分,所以就会出现'缺失的现象

SQL> select dump('管1',16) from dual;

DUMP('管1',16)
----------------------
Typ=96 Len=3: b9,dc,31
读的时候  b9  (dc,31)同样的测试可以看到:
SQL> select dump('理12',16) from dual;

DUMP('理12',16)
-------------------------
Typ=96 Len=4: c0,ed,31,32
读取的顺序 c0 (ed 31 32)

SQL> select dump('理1',16) from dual;
ERROR:
ORA-01756: quoted string not properly terminated
    读取的顺序 c0 (ed 31 39),把引号吃掉了
SQL> select dump('理发',16) from dual;

DUMP('理发',16)
-------------------------
Typ=96 Len=4: c0,ed,b7,a2
          读取的顺序为c0 (ed,b7, a2)

通过上面的分析就很容易知道为什么会出现引号缺省的问题了。通过这个问题的解决对字符集的理解大大加深了,谢谢各位的帮助。


不过你提到的东西,我很是陌生? 初步读下来,还不是很理解。我需要记住你的这个帖子,将来有机会好好分析你说的内容。
分享到:
评论

相关推荐

    Oracle11g 字符集 AL32UTF8 修改为ZHS16GBK

    在Oracle11g环境下,可能会遇到需要更改数据库字符集的情况,例如从AL32UTF8修改为ZHS16GBK。这种变更通常发生在需要支持特定语言环境的应用场景中,尤其是当应用主要面向中文用户时,采用ZHS16GBK字符集可以更好地...

    oracle库字符集ZHS16GBK到AL32UTF8的分析研究及方案

    个人工作总结,仅供参考。oracle库字符集ZHS16GBK到AL32UTF8的分析研究及方案,原因是系统使用中支持维文的显示。

    修改oracle字符集 将原al32utf8修改为zhs16gbk

    案例:从Linux导出的数据导入到windows环境中发现字符集安装时候忘了修改为zhs16gbk(是原来的al32utf8)。

    修改ORACLE11G字符集

    - **修改内部字符集**:使用`alter database characterset internal_use AL32UTF8;`命令来指定新的内部字符集。这里以UTF-8为例,根据实际情况选择合适的字符集。 - **再次关闭数据库**:执行`shutdown immediate;`...

    oracle 字符集

    例如,如果需要将一个使用`AL32UTF8`字符集的字符串转换为`ZHS16GBK`字符集,可以使用以下PL/SQL代码: ```plsql DECLARE str VARCHAR2(100) := '你好,世界!'; BEGIN str := DBMS_CONVERT_CHARSET.CONVERT(str, ...

    Oracle 字符集详解

    常见的Oracle字符集有AL32UTF8(支持Unicode的UTF-8编码)、WE8ISO8859P1(西欧字符集)、ZHS16GBK(简体中文GB18030编码)等。 六、多语言环境下的字符集配置 在处理多语言数据时,Oracle提供了NLSSORT参数来调整...

    oracle 中文字符集问题

    - **AL32UTF8**:通用的多字节字符集,支持几乎所有的Unicode字符,是Oracle推荐的字符集之一。 3. **Unicode字符集** - **AF16UTF16**:基于Unicode的16位编码,每个字符占用两个字节。 - **AL32UTF8**:基于...

    Oracle字符集专题

    Oracle支持多种字符集,如US7ASCII、WE8ISO8859P1、AL32UTF8等,每种字符集都有其特定的覆盖范围和适用场景。 Oracle字符集分为两种类型:客户端字符集和服务器字符集。客户端字符集用于显示和输入数据,而服务器...

    Oracle 修改字符集

    - **国家字符集**(National Character Set):如`AL32UTF8`,主要用于存储Unicode数据。 - **内部使用字符集**(Internal Use Character Set):如`ZHS16GBK`,用于存储非Unicode数据,主要用于内部处理。 3. **...

    oracle数据库导入导出命令! 更改字符集

    - **字符集识别**:Oracle数据库支持多种字符集,如AL32UTF8、WE8ISO8859P1等,不同的字符集用于支持不同语言和特殊字符。在导入导出过程中,确保源和目标数据库的字符集兼容至关重要,否则可能导致乱码。 - **字符...

    Oracle字符集问题

    在处理多语言环境时,选择Unicode字符集如AL32UTF8通常更为安全,因为它支持广泛的语言,减少了字符集不匹配的问题。 总之,Oracle字符集是数据库设计和管理中的一个重要概念,它影响着数据的存储、检索和展示。...

    java连接AmericanascII7字符集oracle例子

    在这种情况下,通常会考虑升级到支持更多字符的字符集,如AL32UTF8(Unicode UTF-8编码),以保证数据的正确显示和存储。 在实际项目中,还可能涉及到事务管理、异常处理、连接池配置等更复杂的操作。为了提高性能...

    查看oracle dmp字符集的小工具

    不同的数据库可能采用不同的字符集,如AL32UTF8(Unicode UTF-8编码)或WE8ISO8859P1(西欧语言的ISO 8859-1编码)。当从一个字符集迁移到另一个字符集时,必须知道源DMP文件的字符集,以便进行相应的转换设置,防止...

    修改数据库字符集修改数据库字符集.doc

    最后,使用`ALTER DATABASE`命令更改数据库的本地字符集为ZHS16GBK(GBK的双字节实现)和国际字符集为AL16UTF16(支持Unicode的字符集)。 2. **处理错误信息**: - 当提示`ORA-12717`时,表示数据库中存在NCLOB、...

    Oracle 字符集的查看和修改

    多字节编码又分为变长和定长两种,前者如AL32UTF8,用于支持亚洲语言,后者如AF16UTF16,是Unicode的16位编码,适用于所有语言。 Unicode 是一个全球性的字符编码标准,旨在涵盖所有已知字符,确保每个字符都有唯一...

    修改Oracle数据库字符集的方法

    例如,如果当前字符集是`AL32UTF8`,则新字符集应该是能够包含所有旧字符集中的字符的字符集。 - **尝试直接更改**(通常会失败): ```sql SQL> alter database character set zhs16gbk; ERROR at line 1: ORA...

    修改oracle字符集.rar

    安装ORACLE数据库,字符集默认是AL32UTF8,有时需要改变数据库字符集,改成ZHS16GBK,资源里面是修改步骤。

Global site tag (gtag.js) - Google Analytics