`
yangzb
  • 浏览: 3468825 次
  • 性别: 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 .

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

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

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

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

    修改oracle字符集.rar

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

    修改ORACLE11G字符集

    文中详细描述了如何修改ORACLE11G字符集的方法和步骤

    linux 下修改字符集的问题

    当装完oracle11g由于当时装的匆忙发现数据库的编码不对,显示编码为AL32UTF,要想显示中文需要改成ZHS16GBK.

    oracle 字符集

    oracle字符集格式说明,NLS_LANG=<Language>_<Territory>.<Clients Characterset>

    数据库服务器字符集更改步骤

    10 数据库服务器字符集更改步骤 问题描述: 在客户端插入字符“咪咪”,从数据库中查询显示时出现乱码 处理步骤: 10.1 对数据库做全库导出,备份全库数据,以防故障发生 首先设定客户端的字符集,必须以ZHS16GBK的...

    Oracle 8i字符集乱码问题析及其解决办法

    Oracle 8i字符集乱码问题析及其解决办法

    MySQL 编码utf8 与 utf8mb4 utf8mb4_unicode_ci 与 utf8mb4_general_ci

    utf8mb4 已成为 MySQL 8.0 的默认字符集,在MySQL 8.0.1及更高版本中将 utf8mb4_0900_ai_ci 作为默认排序规则。 新项目只考虑 utf8mb4 UTF-8 编码是一种变长的编码机制,可以用1~4个字节存储字符。 因为历史遗留问题...

    dbms_obfuscation_toolkit加密解密数据

    dbms_obfuscation_toolkit加密解密数据

    Oracle 数据库多语言入库问题的解决方案

    Oracle 数据库多语言入库问题的解决方案 本文通过研究Oracle 数据库如何成功实现多语言入库,给出了一种实现...文、韩文、阿拉伯文等在默认字符集为ZHS16GBK,国家字符集为AL16UTF16 的数据库的 入库需要特殊的方法。

    Mysql中校对集utf8_unicode_ci与utf8_general_ci的区别说明

    下面摘录一下Mysql 5.1中文手册中关于utf8_unicode_ci与utf8_general_ci的说明: 当前,utf8_unicode_ci校对规则仅部分支持Unicode校对规则算法。一些字符还是不能支持。并且,不能完全支持组合的记号。这主要影响...

    SQLserver排序规则基本概念探索

    对于海外项目很痛苦啊 .Oracle 有AL32UTF8 ,MySQL 有UTF8 ,那SQL Server 有吗? 基本概念 ASCII编码 在计算机发明后不久,计算机只在美国用。他们创造出了ASCII编码,来表示:空格、标点符号、数字、大小写字母...

    cognos安装教程

    cognos 安装 步骤一:首先为ReportNet新建一个数据库。以oracle为例,为ReportNet分配一个具有创建,删除,更新表和视图权限的用户。并把oracle数据库的字符集设为:AL32UTF8或AL16UTF16。

    Linux下Oracle设置定时任务备份数据库的教程

    1、查看数据库的字符集 数据库的字符集必须和Linux下设置的环境变量一致,不然会...查询结果为:NLS_CHARACTERSET AL32UTF8 2、 用oracle用户登录oracle服务器,创建相关的目录 创建备份数据的目录 mkdir -p /home/ora

    MySQL抛出Incorrect string value异常分析

    原来问题出在mysql上,mysql如果设置编码集为utf8那么它最多只能支持到3个字节的UTF-8编码,而4个字节的UTF-8字符还是存在的,这样一来如果你建表的时候用的utf8字符集出异常就理所当然了。 解决方法很简单,修改

    查看oracle数据库的编码及修改编码格式的方法

    AL32UTF8 这其来源于props$,这是表示数据库的字符集。 oracle客户端编码 SQL> select * from nls_instance_parameters where parameter='NLS_LANGUAGE'; PARAMETER ——————– VALUE ——————–

    Mysql数据库乱码问题:Incorrect string value

     这里一共显示了4中字符集,Server characterset是数据库服务器的编码,DB characterset是数据库的编码,client characterset是客户端的编码,conn characterset是建立连接时使用的编码。为了很好的兼容英文和中文...

Global site tag (gtag.js) - Google Analytics