本文将通过实验来演示一下Oracle字符集“转码”的确认过程。
曾经分享过的有关字符集文章如下:
《查看本地windows的字符集方法》
http://space.itpub.net/519536/viewspace-580610
《【字符集】“客户终端字符集”、“NLS_LANG”环境变量以及“数据库字符集”》
http://space.itpub.net/519536/viewspace-615345
《【字符集】处理Toad显示乱码及Windows XP下无法插入“某些汉字”问题》
http://space.itpub.net/519536/viewspace-615379
OK,现在开始我们的实验之旅。
1.实验环境说明
客户端是Windows XP操作系统的SQL*Plus程序,客户端字符集是936(对应Oracle的ZHS16GBK字符集);
数据库版本是Oracle 10g,数据库字符集是AL32UTF8;
NLS_LANG参数将在实验中进行指定。
1)确认客户端字符集
C:\>chcp
活动代码页: 936
注释:936对应Oracle的ZHS16GBK字符集。
2)查看数据库版本信息:
sec@ora10g> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
3)确认数据库的字符集:
sec@ora10g> col PARAMETER for a20
sec@ora10g> col value for a20
sec@ora10g> select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET';
PARAMETER VALUE
-------------------- --------------------
NLS_CHARACTERSET AL32UTF8
2.实验中将会涉及到的两种场景
“转码”场景:设置客户端的NLS_LANG与客户端字符集一致,这里是ZHS16GBK;
“非转码”场景:设置客户端的NLS_LANG与数据库服务器端字符集一致,此处是AL32UTF8.
关于如何设置NLS_LANG参数,请参考下面文章:
《【NLS_LANG】不同操作系统平台NLS_LANG环境变量的查看与设置方法》
http://space.itpub.net/519536/viewspace-580623
在这个实验中,为了方便,我将采用set命令设置字符集。您可以按照自己的习惯去设置。
3.创建实验表T
sec@ora10g> create table t (x number(1), client_characterset varchar2(10), nls_lang varchar2(10), database_characterset varchar2(10), y varchar2(10));
Table created.
sec@ora10g> desc t;
Name Null? Type
----------------------------------- -------- ------------------------
X NUMBER(1)
CLIENT_CHARACTERSET VARCHAR2(10)
NLS_LANG VARCHAR2(10)
DATABASE_CHARACTERSET VARCHAR2(10)
Y VARCHAR2(10)
T表包含五个字段,分表表示序号、客户端字符集、客户端NLS_LANG设置情况以及数据库服务器字符集设置情况。
4.两种NLS_LANG设置方法下分别插入一条数据
1)当客户端的NLS_LANG设置为ZHS16GBK时,我们插入第一条记录(“转码”场景)。
C:\>set nls_lang=AMERICAN_AMERICA.ZHS16GBK
C:\>sqlplus sec/sec@ora10g
SQL*Plus: Release 10.2.0.3.0 - Production on Fri Feb 5 19:21:31 2010
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning and Data Mining options
sec@ora10g> insert into t values (1,'ZHS16GBK','ZHS16GBK','AL32UTF8','圣');
1 row created.
sec@ora10g> commit;
Commit complete.
2)当客户端的NLS_LANG设置为AL32UTF8时,我们插入第二条记录(“非转码”场景)。
C:\>set nls_lang=AMERICAN_AMERICA.AL32UTF8
C:\>sqlplus sec/sec@ora10g
SQL*Plus: Release 10.2.0.3.0 - Production on Fri Feb 5 20:41:15 2010
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning and Data Mining options
sec@ora10g> insert into t values (2,'ZHS16GBK','AL32UTF8','AL32UTF8','圣');
1 row created.
sec@ora10g> commit;
Commit complete.
5.两种NLS_LANG设置方法下分别查看刚刚插入的两条数据
1)当客户端的NLS_LANG设置为ZHS16GBK时(“转码”场景)。
sec@ora10g> col x for 9
sec@ora10g> col CLIENT_CHARACTERSET for a8
sec@ora10g> col NLS_LANG for a8
sec@ora10g> col DATABASE_CHARACTERSET for a8
sec@ora10g> col y for a4
sec@ora10g> col dump for a50
sec@ora10g> select t.*,dump(y,1016) dump from t order by 1;
X CLIENT_C NLS_LANG DATABASE Y DUMP
-- -------- -------- -------- ---- --------------------------------------------------
1 ZHS16GBK ZHS16GBK AL32UTF8 圣 Typ=1 Len=3 CharacterSet=AL32UTF8: e5,9c,a3
2 ZHS16GBK AL32UTF8 AL32UTF8 ? Typ=1 Len=2 CharacterSet=AL32UTF8: ca,a5
2)当客户端的NLS_LANG设置为AL32UTF8时(“非转码”场景)。
sec@ora10g> col x for 9
sec@ora10g> col CLIENT_CHARACTERSET for a8
sec@ora10g> col NLS_LANG for a8
sec@ora10g> col DATABASE_CHARACTERSET for a8
sec@ora10g> col y for a4
sec@ora10g> col dump for a50
sec@ora10g> select t.*,dump(y,1016) dump from t order by 1;
X CLIENT_C NLS_LANG DATABASE Y DUMP
-- -------- -------- -------- ---- --------------------------------------------------
1 ZHS16GBK ZHS16GBK AL32UTF8 鍦? Typ=1 Len=3 CharacterSet=AL32UTF8: e5,9c,a3
2 ZHS16GBK AL32UTF8 AL32UTF8 圣 Typ=1 Len=2 CharacterSet=AL32UTF8: ca,a5
BTW:有关dump函数的使用方法可以参考Oracle的官方文档
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions046.htm#SQLRF00635
我这里将return_fmt指定为“1016”,这样会指示出字符集和字符的16进制编码内容。
6.分析与结论
1)“圣”字在ZHS16GBK字符集下的编码是“ca,a5”
这个信息可以从微软的936字符集(ZHS16GBK)中查询得到。
http://www.microsoft.com/globaldev/reference/dbcs/936/936_CA.mspx
2)“圣”字在AL32UTF8字符集下的编码是“e5,9c,a3”
怎么确认“圣”字在UTF8字符集下的编码呢?使用UltraEdit的十六进制编辑模式可以完成这个任务。
将汉字“圣”粘贴到空白的UltraEdit中,依次点选“文件” --> “转换” --> “ASCII转UTF-8(Unicode 编辑)”,然后再一次点选“编辑” --> “十六进制函数” --> “十六进制编辑”(反复切换十六进制编辑模式亦可使用Ctrl+H快捷键来完成),OK,此时便可以得到“圣”字在UTF8字符集下的编码是“E5 9C A3”。
当然,确认“圣”字在ZHS16GBK字符集下的编码也可以使用UltraEdit来完成。
3)结论一
当客户端的NLS_LANG设置为ZHS16GBK时,“圣”字发生了转码,由ZHS16GBK编码“ca,a5”转成了AL32UTF8编码“e5,9c,a3”;
4)结论二
当客户端的NLS_LANG设置为AL32UTF8时,“圣”字没有发生转码,直接以客户端的ZHS16GBK编码“ca,a5”存储在数据库中。
5)“?”的由来
当客户端的NLS_LANG设置为ZHS16GBK时,查询得到的“?”是由UTF-8编码“ca,a5”转换为ZHS16GBK编码后的产物。
6)“鍦?”的由来
这个“鍦”字读作“shi1”(参考:http://www.zdic.net/zd/zi/ZdicE9Zdic8DZdicA6.htm)
因为此时NLS_LANG设置为AL32UTF8,客户端获取数据库信息时将不进行转码,因此在客户端显示的时候将使用“e5,9c,a3”这个编码在936字符集(ZHS16GBK)中寻找匹配的内容。前面的“e5,9c”正好拼接成了“鍦”字,因此“鍦”字便展现在了我们面前。
这个“鍦”字的编码可以在下面的链接中查询到。
http://www.microsoft.com/globaldev/reference/dbcs/936/936_E5.mspx
7.小结
Oracle字符集相关知识涉及面较广,需要静下心来仔细思考其中蕴含的原理。
本文通过实验给大家展示了有关“转码”的相关内容,供参考,希望对大家有帮助。
Good luck.
secooler
10.02.05
-- The End --
分享到:
相关推荐
总的来说,理解Oracle字符集转换的规则并遵循最佳实践,是确保数据完整性和一致性的重要保障。在处理跨字符集的数据迁移时,应特别关注可能的风险,提前做好规划和测试,以防止潜在的数据损失。
- Oracle的监听器(listener.ora)也需要配置正确的字符集,以确保网络传输过程中不发生乱码。 9. **监控和测试**: - 输入不同类型的汉字,确保在查询结果、报表、备份等场景下都能正常显示。 10. **解决问题**...
通过上述两步,可以在AS400 V5R1之前版本的系统中成功地处理包含简体或繁体中文字符集为37的表字段,并将其导入到Oracle数据库中。这种方法不仅解决了字符集不兼容的问题,还确保了数据的准确性和完整性。对于那些...
总之,解决“CDC-MQ数据库生僻字转码”问题需要理解字符集的原理,正确进行数据的编码和解码,并确保整个数据流转过程中的字符集一致性。通过上述方法,可以有效地防止和处理生僻字乱码问题,保证数据的完整性和准确...
字符编码是计算机用来表示字符集的一种方式。常见的字符编码有ASCII、GB2312、GBK、UTF-8等。其中,UTF-8是一种变长字符编码,用于Unicode编码标准,兼容ASCII,并且能够高效地存储大多数非英文字符。 ##### 2. UTF...
它通过将每3个8位字节的数据转换为4个6位的字符,以确保所有标准ASCII字符集的字符都能被表示。在图片处理中,BASE64编码常用来将图片数据转换为文本格式,便于在网络传输或存储时使用。 2. **Blob类型**:Blob是...
1. 数据库设置:数据库管理系统(如MySQL、Oracle、SQL Server)自身有默认的字符集设置。如果数据库的默认编码与应用程序的编码不一致,可能导致乱码。 2. 连接字符串:在连接数据库时,我们需要指定使用的字符集...
面试者需要能够处理数据库层面的问题,如字符集转码。 4. **Linux知识**:面试题目中有询问如何查询Linux运行的进程,正确答案是`ps`命令。面试者应具备基本的Linux操作系统知识,这对软件开发和系统管理至关重要。...
- `encoding`: 指定使用的字符集编码,默认为`ISO-8859-1`。例如:`UTF-8`。 - `quote_style`: 指定是否对引号进行编码,默认为`0`表示不编码。 **示例**: ```sql SELECT UTL_URL.ESCAPE('中国', 'UTF-8') FROM ...
8. **类似DECODE的转码操作:** 可以使用`CASE WHEN`语句来实现类似Oracle中DECODE的功能。 9. **类似CHARINDEX查找字符在字串中的位置:** 使用`POSITION`函数可以找到子字符串在主字符串中的位置。 10. **类似...
5. **类似DECODE的转码操作:** 使用`CASE`语句实现类似Oracle DECODE的功能,根据不同的条件返回不同的值。 6. **类似CHARINDEX查找字符在字符串中的位置:** 使用`POSITION`函数来查找一个字符串在另一个字符串中的...
在存储过程中返回结果集通常涉及声明和打开游标,然后将其作为输出参数返回。例如: ```sql CREATE PROCEDURE MyProcedure (OUT cursor_result CURSOR FOR SELECT * FROM my_table) BEGIN DECLARE CONTINUE HANDLER...
- **从存储过程返回结果集(游标)的用法**:使用`RETURN NEXT FROM cursor_name`。 - **类型转换函数**:如`CAST(column AS data_type)`进行类型转换。 - **存储过程的互相调用**:通过`CALL 存储过程名称`来调用其他...
- **从存储过程返回结果集的用法**:使用`RETURN QUERY`语句返回查询结果,例如: ```sql CREATE PROCEDURE get_data() BEGIN RETURN QUERY SELECT * FROM table_name; END ``` - **类型转换函数**:使用`...
- 创建数据库:在MySQL中,可以使用`CREATE DATABASE`命令创建数据库,并指定字符集,例如`DEFAULT CHARACTER SET 'utf8'`。需要注意,`IF NOT EXISTS`关键字应放在数据库名后面。 - 删除数据库:使用`DROP ...