ITPub博客

首页 > Linux操作系统 > Linux操作系统 > UTF8

UTF8

原创 Linux操作系统 作者:zhouwf0726 时间:2019-02-20 14:12:06 0 删除 编辑

utf8 全包容了gbk ,并没有超集和子集的关系;
8i 的数据库 的 utf8 是 4位定长的字符编码;
9i 和以上数据库的utf8 有4位定长AL32UTF8和 不定长的 UTF8 ,都是unicode编码;
其中,utf8 编码中字符大多是三字节的编码,一个汉字是 3字节的编码;
zhs16gbk 并不是unicode 编码,只是提供了对gbk汉字编码的支持, 一个汉字为双字节;
utf8 对于 zhs16gbk 中的所有编码都有唯一的编码以之对应,所以我说utf8 全包容了gbk;
当然,utf8作为一种unicode 编码,他还提供 global character 的支持;
假如设置得当,从 zhs16gbk 到utf8 是可以实现无损耗的字符转换的;

////


SQL> create table t(id varchar2(10));

表已创建。

SQL> insert into t values('aaaaaaaaaa');

已创建 1 行。

SQL> insert into t values('aaaaaaaaaaa');
insert into t values('aaaaaaaaaaa')
*
第 1 行出现错误:
ORA-12899: value too large for column "ZWF"."T"."ID" (actual: 11, maximum: 10)


SQL> insert into t values('中国');

已创建 1 行。

SQL> insert into t values('中国中国');
insert into t values('中国中国')
*
第 1 行出现错误:
ORA-12899: value too large for column "ZWF"."T"."ID" (actual: 12, maximum: 10)


SQL> insert into t values('中国中');

已创建 1 行。

SQL> COL DMP FORMAT A30

SQL> SELECT ID,DUMP(ID) DMP,ASCII(ID) FROM T;

ID DMP ASCII(ID)
---------- ------------------------------ ----------
aaaaaaaaaa Typ=1 Len=10: 97,97,97,97,97,9 97
7,97,97,97,97

中国 Typ=1 Len=6: 228,184,173,229,1 14989485
55,189

中国中 Typ=1 Len=9: 228,184,173,229,1 14989485
55,189,228,184,173

SQL> COL PARAMETER FOR A20
SQL> COL VALUE FOR A20

SQL> SELECT * FROM NLS_DATABASE_PARAMETERS;

PARAMETER VALUE
--------------- --------------------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENC AMERICA
Y

NLS_NUMERIC_CHA .,
RACTERS

NLS_CHARACTERSE UTF8 --目前我们的设置
T

PARAMETER VALUE
--------------- --------------------

NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUA AMERICAN
GE

NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_F DD-MON-RR HH.MI.SSXF
ORMAT F AM


PARAMETER VALUE
--------------- --------------------
NLS_TIME_TZ_FOR HH.MI.SSXFF AM TZR
MAT

NLS_TIMESTAMP_T DD-MON-RR HH.MI.SSXF
Z_FORMAT F AM TZR

NLS_DUAL_CURREN $
CY

NLS_COMP BINARY
NLS_LENGTH_SEMA BYTE

PARAMETER VALUE
--------------- --------------------
NTICS

NLS_NCHAR_CONV_ FALSE
EXCP

NLS_NCHAR_CHARA AL16UTF16
CTERSET

NLS_RDBMS_VERSI 10.1.0.4.0
ON


已选择20行。

字符集扫描工具(zt):

一、the Character Set Scanner Utility的作用  分析字符数据转换到新的字符集的可行性和可能存在的问题并给出一个评估报告,用户可依据该报告确定如何进行字符集转换。
  该工具主要测试在转换到新的字符集时数据的字符编码会作什么改变;是否能成功转换到新的字符集;转换后的数据是否适合当前列的大小。只检测CHAR, VARCHAR2, LONG, CLOB, NCHAR, NVARCHAR2, and NCLOB数据类型的列,不测试LONG, CLOB, and NCLOB数据类型的大小。
  
  二、工具的准备
  在使用前必须执行一个SQL脚本CSMINST.SQL,该脚本位于$Oracle_home/rdbms/admin,只须执行一次,主要用于建立与扫描相关的一些资源。
  cd <脚本所在的目录>
  sqlplus system/manager
  SQL> start csminst.sql
  
  三、工具的执行
  执行扫描的用户必须具备DBA权限。在命令行下执行Csscan,有三种执行方式:
  1、使用参数文件 csscan system/manager PARFILE=filename
  2、命令行直接给出参数 csscan system/manager full=y tochar=zhs16gbk array=10240 process=3
  3、使用交互模式 csscan system/manager
  
  四、参数说明
  要获得使用帮助在命令行下输入 csscan help=y
  ARRAY:定义用于提取数据的buffer大小,该值决定扫描时每次读取数据的行数,因此影响扫描时间的长短;如果char和varchar2列的大小之和大于该值,则每次读取一行数据;如果包含LONG, CLOB, or NCLOB列则每次也只读取一行。
  缺省值:10240;最小值:4096;最大值:无限。
  BOUNDARIES:用于在生成应用数据报告时按列大小分组报告的分界值,例如设该值为(10,50,100),则在生成的评估报告中应用数据按char(1..10),char(11..50),char(51..100)分组列出,VARCHAR2, NCHAR, and NVARCHAR2 数据类型一样。
  CAPTURE:确定是否获取可转换行的信息到表CSM$ERRORS,主要用于选择数据eXPort/import到目标字符集。
  取值范围:Y or N ,缺省值:N。
  FEEDBACK:定义显示扫描进度的每个点代表已扫描多少行。
  缺省值:无;最小值:100;最大值:100000 。
  FROMCHAR:说明数据库CHAR, VARCHAR2, LONG, CLOB数据类型的实际字符集,缺省使用数据库的字符集。
  FROMNCHAR:说明数据库NCHAR, NVARCHAR2, NCLOB数据类型的实际国家字符集,缺省使用数据库的国家字符集。
  FULL:是否执行全数据库扫描,如果是则扫描整个数据库包括数据字典。
  取值范围:Y or N ,缺省值:N。
  HELP:显示关于所有参数的帮助信息。
  取值范围:Y or N ,缺省值:N。
  LASTRPT:指示是否产生基于上一次扫描的统计信息上的扫描报告。
  取值范围:Y or N ,缺省值:N。
  LOG:产生报告的文件名,缺省为scan;
  有三个文件:扫描汇总报告scan.txt,独立的例外报告scan.err,扫描日志文件scan.out。
  MAXBLOCKS:定义每个表的最大块的大小,以便大表能分成小块给某个扫描进程。
  缺省值:无;最小值:1000;最大值:无限。
  PARFILE:指定参数文件。
  PROCESS:定义并发扫描进程数。
  缺省值:1;最小值:1;最大值:32。
  SUPPRESS:定义每个表的最大例外数,扫描记录例外信息到表CSM$ERRORS中,该参数限制记录每个表最大的例外数。
  缺省值:无限;最小值:0;最大值:无限。
  TABLE:指定扫描特定的表。
  TOCHAR:指定需要转换的目标字符集。
  TONCHAR:指定需要转换的目标国家字符集,如果未指定将不扫描NCHAR, NVARCHAR2, NCLOB数据类型的数据 。
  USER:指定要扫描的表的拥有者,如果未指定TABLE参数,则扫描该用户所有表。
  USERID:执行扫描的用户名和密码(如不在本地还需要加上连接字符串),未输密码,系统将会提示你输入。
  
  五、扫描结果
  扫描将产生两个结果报告:汇总报告和例外报告,汇总报告文件后缀为.txt,例外报告文件后缀为.err。
  汇总报告包括数据库大小(每个表空间的大小和使用情况)、扫描参数、扫描总结、数据字典转换总结、应用数据转换总结、应用数据转换按列大小总结、每张表可转换数据分布、每个列可转换数据分布、重建的索引。
  扫描总结依扫描模式可包含两个内容:数据字典和应用数据;他们又分别有三种情况:所有数据保持不变、所有数据可以转换、一些数据不可转换。
  数据字典转换总结和应用数据转换总结分别对相应数据的可转换情况按数据类型统计数量,其也分为三种情况:保持不变、可转换、例外(不可转换)。
  应用数据转换按列大小总结同上,只是依据BOUNDARIES参数按列大小统计。
  每张表可转换数据分布和每个列可转换数据分布分别按表和按列统计可转换数据和例外数据的分布数量。
  重建的索引列出在import时能够重建的索引。
  例外报告包括扫描参数和应用数据例外。
  应用数据例外列出所有例外数据(不能被转换),以便这些数据在必要时进行修改。有两种类型的例外:大小超出和损失转换;大小超出指的是数据转换为新的字符集后会比原来的字符宽;损失转换的这些数据需在转换前被修正合适新字符集或将被转换为乱码。

字符集相关问题(zt):

在国内外大中型数据库管理系统中,把ORACLE作为数据库管理平台的用户比较多。

ORACLE 不论是数据库管理能力还是安全性都是无可非议的,但是,它在汉字信息的显示方面着实给中国用户带来不少麻烦,笔者多年从事ORACLE数据库管理,经常收到周围用户和外地用户反映有关ORACLE数据库汉字显示问题的求援信,主要现象是把汉字显示为不可识别的乱码,造成原来大量信息无法使用。本文将就这一问题产生的原因和解决办法进行一些探讨,供存在这方面问题的用户朋友参考。
  
  1、原因分析
  通过对用户反映情况的分析,发现字符集的设置不当是影响ORACLE数据库汉字显示的关键问题。那么字符集是怎么一会事呢?字符集是ORACLE 为适应不同语言文字显示而设定的。用于汉字显示的字符集主要有ZHS16CGB231280,US7ASCII,WE8ISO8859P1等。字符集不仅需在服务器端存在,而且客户端也必须有字符集注册。服务器端,字符集是在安装ORACLE时指定的,字符集登记信息存储在ORACLE数据库字典的V$NLS_PARAMETERS表中;客户端,字符集分两种情况,一种情况是sql*net 2.0以下版本,字符集是在windows的系统目录下的oracle.ini文件中登记的;另一种情况是sql*net 2.0以上(即32位)版本,字符集是在windows的系统注册表中登记的。要在客户端正确显示ORACLE 数据库汉字信息,首先必须使服务器端的字符集与客户端的字符集一致;其次是加载到ORACLE数据库的数据字符集必须与服务器指定字符集一致。因此,把用户存在的问题归纳分类,产生汉字显示异常的原因大致有以下几种:
  
  1. 1服务器指定字符集与客户字符集不同,而与加载数据字符集一致。
  
  这种情况是最常见的,只要把客户端的字符集设置正确即可,解决办法见2.1。
  
  1. 2服务器指定字符集与客户字符集相同,与加载数据字符集不一致。
  
  这类问题一般发生在ORACLE版本升级或重新安装系统时选择了与原来服务器端不同的字符集,而恢复加载的备份数据仍是按原字符集卸出的场合,以及加载从其它使用不同字符集的ORACLE数据库卸出的数据的情况。这两种情况中,不管服务器端和客户端字符集是否一致都无法显示汉字。解决办法见2.2。
  
  1.3服务器指定字符集与客户字符集不同,与输入数据字符集不一致。
  
  这种情况是在客户端与服务器端字符集不一致时,从客户端输入了汉字信息。输入的这些信息即便是把客户端字符集更改正确,也无法显示汉字。解决办法见2.3。
  
  2.解决办法
  下面将分别对上述三种情况给出解决办法。为了叙述方便,假设客户端使用WINDOWS95/98环境,并已成功地配置了TCP/IP协议,安装了ORACLE的sql*net,sql*pluse产品。
  
  2.1 设置客户端字符集与服务器端字符集一致
  
  假设当前服务器端使用US7ASCII字符集。
  
  (1)查看服务器端字符集
  通过客户端或服务器端的sql*plus登录ORACLE的一个合法用户,执行下列
  SQL语句:
  
  SQL > select * from V$NLS_PARAMETERS
  parameter value
  NLS_LANGUAGE AMERICAN
  NLS_TERRITORY AMERICA
  …. ….
  NLS_CHARACTERSET US7ASCII
  NLS_SORT BINARY
  NLS_NCHAR_CHARACTERSET US7ASCII
  
  从上述列表信息中可看出服务器端ORACLE数据库的字符集为'US7ASCII'。
  
  (2)按照服务器端字符集对客户端进行配置
  配置方法有两种:
  安装ORACLE的客户端软件时指定
  在安装ORACLE的客户端产品软件时,选择与ORACLE服务端一致的字符集(本例为US7ASCII)即可。
  
  修改注册信息的方法
  根据ORACLE 客户端所选sql*net 的版本分为下列两种情况:
  
  a. 客户端为 sql*net 2.0 以下版本
  
  进入Windows的系统目录,编辑oracle.ini文件,用US7ASCII替换原字符
  集,重新启动计算机,设置生效。
  
  b. 客户端为 sql*net 2.0 以上版本
  
  在WIN98 下 运 行REGEDIT,第一步选HKEY_LOCAL_MACHINE,第二步选择SOFTWARE, 第三步选择 ORACLE, 第四步选择 NLS_LANG, 键 入 与服 务 器端 相 同 的 字 符 集(本例为:AMERICAN_AMERICAN.US7ASCII)。
  
  2.2 强制加载数据字符集与服务器端字符集一致
  
  假设要加载数据从原ORACLE数据库卸出时的字符集为US7ASCII,当前ORACLE服务器字符集为WE8ISO8859P1。
  
  下面提供三种解决方法:
  (1) 服务器端重新安装ORACLE
  在重新安装ORACLE 时选择与原卸出数据一致的字符集(本例为US7ASCII)。
  
  加载原卸出的数据。
  
  这种情况仅仅使用于空库和具有同一种字符集的数据。
  
  (2)强行修改服务器端ORACLE当前字符集
  在用imp命令加载数据前,先在客户端用sql*plus登录system DBA用户,执行下列SQL语句进行当前ORACLE数据库字符集修改:
  
  SQL > create database character set US7ASCII
  * create database character set US7ASCII
  ERROR at line 1:
  ORA-01031: insufficient privileges
  
  你会发现语句执行过程中,出现上述错误提示信息,此时不用理会,实际上ORACLE数据库的字符集已被强行修改为US7ASCII,接着用imp命令装载数据。等数据装载完成以后,shutdown 数据库,再startup 数据库,用合法用户登录ORACLE数据库,在sql>命令提示符下,运行select * from V$NLS_PARAMETERS,可以看到ORACLE数据库字符集已复原,这时再查看有汉字字符数据的表时,汉字已能被正确显示。
  
  (3)利用数据格式转储,避开字符集限制
  这种方法主要用于加载外来ORACLE数据库的不同字符集数据。其方法如下:
  
  先将数据加载到具有相同字符集的服务器上,然后用转换工具卸出为foxbase 格式或access格式数据库,再用转换工具转入到不同字符集的ORACLE数据库中,这样就避免了ORACLE字符集的困扰。目前数据库格式转换的工具很多,象power builder5.0以上版本提供的pipeline,Microsoft Access数据库提供的数据导入/导出功能等。转换方法参见有关资料说明。.
  
  2.3匹配字符集替换汉字
  
  对于1.3提到的情况,没有很好的办法,只能先把客户端与服务器端字符集匹配一致后,根据原输入汉字的特征码替换汉字字符部分。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/756652/viewspace-242458/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: perl+xml+ini
请登录后发表评论 登录
全部评论

注册时间:2006-02-22

  • 博文量
    458
  • 访问量
    416640