资料:

很久以来,字符集一直是困扰着众多Oracle爱好者的问题,在此我们就这个问题做一些分析和探讨。

首先,我们要明确什么是字符集?字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包括关系,如us7ascii就是zhs16gbk的子集,从us7ascii到zhs16gbk不会有数据解释上的问题,不会有数据丢失,Oracle对这种问题也要求从子集到超集的导出受支持,反之不行。在所有的字符集中utf8应该是最大,因为它基于unicode,双字节保存字符(也因此在存储空间上占用更多)。

其次,一旦数据库创建后,数据库的字符集是不能改变的。因此,在设计和安装之初考虑使用哪一种字符集是十分重要的。数据库字符集应该是操作系统本地字符集的一个超集。存取数据库的客户使用的字符集将决定选择哪一个超集,即数据库字符集应该是所有客户字符集的超集。

在实际应用中,和字符集问题关系最大的恐怕就是exp/imp了。在做exp/imp时,如果Client 和Server的nls_lang设置是一样的,一般就没有问题的。但是,要在两个不同字符集的系统之间导数据就经常会有这样或那样的问题,如,导出时数据库的显示正常,是中文,当导入到其他系统时,就成了乱码,这也是一类常见问题。

现在,介绍一些与字符集有关的NLS_LANG参数,

NLS_LANG格式:

NLS_LANG = language_territory.charset

有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。其中:language 指定服务器消息的语言。

territory 指定服务器的日期和数字格式。

charset 指定字符集

例如:

AMERICAN_AMERICA.US7SCII

AMERICAN _ AMERICA. ZHS16GBK

还有一些子集可以更明确定义NLS_LANG参数:

DICT.BASE 数据字典基本 表版本

DBTIMEZONE 数据库时区

NLS_LANGUAGE 语言

NLS_TERRITORY 地域

NLS_CURRENCY 本地货币字符

NLS_ISO_CURRENCY ISO货币字符

NLS_NUMERIC_CHARACTERS 小数字符和组 分隔开

NLS_CHARACTERSET 字符集

NLS_CALENDAR 日历系统

NLS_DATE_FORMAT 缺省的日期格式

NLS_DATE_LANGUAGE 缺省的日期语言

NLS_SORT 字符排序序列

NLS_TIME_FORMAT 时间格式

NLS_TIMESTAMP_FORMAT 时间戳格式

……

通过props$动态性能视图,我们可以查看数据库的字符集信息:

$> sqlplus internal

SQL> desc props$

Name Type Nullable Default Comments

NAME VARCHAR2(30)

value$ VARCHAR2(4000) Y

COMMENT$ VARCHAR2(4000) Y

SQL> set arraysize 1

SQL> col value$ format a40

SQL> select name,value$ from props$ where name=‘NLS_CHARACTERSET’;

NAME value$

NLS_CHARACTERSET ZHS16GBK

SQL> select * from sys.props$;

NAME value$

DICT.BASE 2

DBTIMEZONE 0:00

NLS_LANGUAGE AMERICAN

NLS_TERRITORY AMERICA

NLS_CURRENCY $

NLS_ISO_CURRENCY AMERICA

NLS_NUMERIC_CHARACTERS .,

NLS_CHARACTERSET ZHS16GBK

NLS_CALENDAR GREGORIAN

NLS_DATE_FORMAT DD-MON-RR

NLS_DATE_LANGUAGE AMERICAN

NLS_SORT BINARY

NLS_TIME_FORMAT HH.MI. SSXFF AM

NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM

NLS_TIME_TZ_FORMAT HH.MI.

SSXFF AM TZH:TZM

NLS_TIMESTAMP_TZ_FORMAT DD-MON- RR HH.MI. SSXFF AM TZH:TZM

NLS_DUAL_CURRENCY $

NLS_COMP BINARY

NLS_NCHAR_CHARACTERSET ZHS16GBK

NLS_RDBMS_VERSION 8.1.6.0.0

NAME value$

GLOBAL_DB_NAME SCPDB1

EXPORT_VIEWS_VERSION 8

22 rows selected

SQL>

从结果可以看出:

NLS_LANG = AMERICAN _ AMERICA. ZHS16GBK

虽然,数据库的字符集是在create database的时候指定的,以后不允许改变,但在一个已经建立好的数据库上,我们可以通过修改SYS.PROPS$来修改主要是对应客户端的显示,与存储无关。

如:

SQL> conn / as sysdba

Connected.

SQL> SQL> select * from sys.props$

2 WHERE NAME=‘NLS_LANGUAGE’;

NAME value$

NLS_LANGUAGE AMERICAN

SQL> UPDATE sys.PROPS$ SET value$=‘SIMPLIFIED CHINESE’

2 WHERE NAME=‘NLS_LANGUAGE’;

1 row updated

SQL> select * from sys.props$

2 WHERE NAME=‘NLS_LANGUAGE’;

NAME value$

NLS_LANGUAGE SIMPLIFIED CHINESE

通常出现问题的原因,可分为三种:

1. 服务器指定字符集与客户字符集不同,而与加载数据字符集一致。

解决方法:对于这种情况,只需要设置客户端字符集与服务器端字符集一致就可以了,具体操作如下:

* 查看当前字符集:

SQL> select * from sys.props$

2 WHERE NAME=‘NLS_CHARACTERSET’;

NAME value$

NLS_CHARACTERSET ZHS16GBK

可以看出,现在服务器端Oracle数据库的字符集为‘ZHS16GBK’

* 根据服务器的字符集在客户端作相应的配置或者安装Oracle的客户端软件时指定:

如果还没安装客户端,那么在安装客户端时,指定与服务器相吻合的字符集即可;如果已经安装好了客户端,并且客户端为 sql*net 2.0 以下版本,进入Windows的系统目录,编辑oracle.ini文件,用US7ASCII替换原字符集,重新启动计算机,设置生效;否则,如果,客户端为 sql*net 2.0 以上版本,在Win98 下 运 行REGEDIT,第一步选HKEY_LOCAL_MACHINE,第二步选择SOFTWARE, 第三步选择 Oracle, 第四步选择 NLS_LANG, 键 入 与服 务 器 端 相 同 的 字 符 集

(本例为:HKEY_LOCAL_MACHINE/

SOFTWARE/ORACLE/NLS_LANG :AMERICAN _ AMERICA. ZHS16GBK)。

如果是UNIX客户端,则:

SQL> conn / as sysdba

Connected.

SQL> SQL> UPDATE sys.PROPS$ SET value$=‘SIMPLIFIED CHINESE’

2 WHERE NAME=‘NLS_LANGUAGE’;

2. 服务器指定字符集与客户字符集相同,与加载数据字符集不一致。

解决方法:强制加载数据字符集与服务器端字符集一致。要做到这一点,可以通过重新创建数据库,并选择与原卸出数据一致的字符集,然后IMP数据,这种情况仅仅适用于空库和具有同一种字符集的数据。

解决这类问题,也可以先将数据加载到具有相同字符集的服务器上,然后用转换工具卸出为foxbase 格式或access格式数据库,再用转换工具转入到不同字符集的Oracle数据库中,这样就避免了Oracle字符集的困扰。目前数据库格式转换的工具很多,像power builder5.0以上版本提供的pipeline及Microsoft Access数据库提供的数据导入/导出功能等。

3. 服务器指定字符集与客户字符集不同,与输入数据字符集不一致。

对于这种情况,目前为止都还没有太好的解决方法。

通过上面的了解,我们知道,导致在后期使用数据库时出现种种关于字符集的问题,多半是由于在数据库设计、安装之初没有很好地考虑到以后的需要,所以,我们完全可以通过在服务器上和客户端使用相同的字符集来避免由此类问题引出的麻烦

怎样修改查看Oracle字符集

a.数据库服务器字符集select * from nls_database_parameters,其来源于props$,是表示数据库的字符集。

b.客户端字符集环境select * from nls_instance_parameters,其来源于v$parameter,

表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表

c.会话字符集环境 select * from nls_session_parameters,其来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如果会话没有特殊的设置,将与nls_instance_parameters一致。

客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。如果多个设置存在的时候,alter session>环境变量>注册表>参数文件

实际情况

我用select * from nls_database_parameters

PARAMETER                      VALUE

------------------------------ ------------------------------

NLS_LANGUAGE                   AMERICAN

NLS_TERRITORY                  AMERICA

NLS_CURRENCY                   $

NLS_ISO_CURRENCY               AMERICA

NLS_NUMERIC_CHARACTERS         .,

NLS_CHARACTERSET               ZHS16GBK

NLS_CALENDAR                   GREGORIAN

NLS_DATE_FORMAT                DD-MON-RR

NLS_DATE_LANGUAGE              AMERICAN

NLS_SORT                       BINARY

NLS_TIME_FORMAT                HH.MI.SSXFF AM

PARAMETER                      VALUE

------------------------------ ------------------------------

NLS_TIMESTAMP_FORMAT           DD-MON-RR HH.MI.SSXFF AM

NLS_TIME_TZ_FORMAT             HH.MI.SSXFF AM TZR

NLS_TIMESTAMP_TZ_FORMAT        DD-MON-RR HH.MI.SSXFF AM TZR

NLS_DUAL_CURRENCY              $

NLS_COMP                       BINARY

NLS_LENGTH_SEMANTICS           BYTE

NLS_NCHAR_CONV_EXCP            FALSE

NLS_NCHAR_CHARACTERSET         AL16UTF16

NLS_RDBMS_VERSION              10.2.0.1.0

说明我在创建数据库时指定的字符集是ZHS16GBK,我用

update sys.props$ set value$='AL32UTF8' where name='NLS_CHARACTERSET';

修改了字符集,但插入中文时仍然有问题,这或许就如上面资料所说的通过修改SYS.PROPS$来修改主要是对应客户端的显示,与存储无关,

所以仍旧是乱码。

然后我重新创建了个数据库,指定字符集为AL32UTF8,插入中文就没问题了。

可见我们如果要在数据库中显示中文,在创建数据库时一定哟指定好所用的字符集。

oracle数据库表中文乱码,oracle数据库中文乱码的原因与解决相关推荐

  1. oracle 内部表连接方式,ORACLE 表连接方式

    一表的连接 表的连接是指在一个SQL语句中通过表与表之间的关联,从一个或多个表检索出相关的数据.连接是通过SQL语句中FROM从句的多个表名,以及WHERE从句里定义的表之间的连接条件来实现的.如果一 ...

  2. oracle 查看表空间总量,oracle 查看表空间以及剩余量

    --1.查看表空间的名称及大小 SELECT t.tablespace_name, round(SUM(bytes / (1024 * 1024)), 0) ts_size FROM dba_tabl ...

  3. oracle 内部表连接方式,oracle表连接方式

    ORACLE表连接方式及常见用法(二) /2010-12-22 13:30:13 /个人分类: 一 引言 数据仓库是目前已知的比较成熟和被广泛采用的解决方案,用于整合电信运营内部所有分散的原始业务数据 ...

  4. 第100篇博文纪念 | C# 根据数据库表结构生成DOC数据库文档

    一.目标 下图是我们要实现的目标: 二.实现 原理非常简单,首先制作样式模版,可以参照文章2,将排版好的Word另存为html,然后复制粘贴到aspx页面中,然后从数据库读取表以及字段信息,动态的插入 ...

  5. oracle导入 表 卡住了,oracle数据库怎么导入dmp,只导入数据不导入表结构?

    使用方法: Exp parameter_name=value or Exp parameter_name=(value1,value2--) 只要输入参数help=y就可以看到所有帮助. EXP常用选 ...

  6. oracle通过表空间文件进行数据库恢复,oracle通过DBF恢复数据

    前一段客户运行的项目数据库突然崩溃,并且没有进行数据备份.解决办法: 1,安装oracle 10g数据库并创建一个要恢复的数据库相同一的实例(注意:最好是新安装的数据库,并且安装的数据库尽量和要恢复的 ...

  7. php mysql oracle数据库表结构图_创建数据库表

    数据库的作用:1.有结构的存储大量数据.2.有效保持数据的一致性.3.方便智能的分析,产生新的有用的信息.4.满足应用的共享和安全的要求. 关系型数据库的基本组成:一个数据库是由一组数据表(table ...

  8. pe系统备份oracle数据库,Oracle 通过表空间文件进行数据库恢复

    操作系统:WindowsXP2 数据库:oracle 10g 由于数据库服务器崩溃,造成了无法进入系统进行数据库备份,只能从光盘的PE系统把oracle相关文件拷贝出来.对于拷贝出来的文件在测试机上进 ...

  9. java实体中文字段_java - Spring JPA实体类是否可以包含不在数据库表中的非数据库字段 - SO中文参考 - www.soinside.com...

    我在SpringBoot中使用Spring JPA和Spring Data Rest.我有一个称为用户的数据库表和该表的实体.我没有此应用程序的控制器.@Entity @Table(name = &q ...

  10. oracle通过表空间文件进行数据库恢复,Oracle数据库表空间恢复方案_oracle

    一. 用户表空间 错误: 在启动数据库时出现ORA-01157,ORA-01110或操作系统级错误例如ORA-07360,在关闭数据库(使用shutdown normal或shutdown immed ...

最新文章

  1. OneFlow 概念清单
  2. LVS的工作原理和相关算法
  3. SD从零开始16 促销计划(Agreements)
  4. 2018-2019 1 20165203 实验五 通用协议设计
  5. 操作系统的运行机制和体系机构
  6. 数据结构 - 二叉排序树BST(创建、遍历、删除节点)
  7. python *args和**kwargs以及序列解包
  8. 多线程的创建方式之实现Callable接口
  9. K8S_Google工作笔记0012---通过二进制方式_部署master组件
  10. opencv将图像转换成二维数组再将数组数据传给新图像
  11. 目前效果最好、应用较广且比较成熟的语音识别模型是什么?
  12. 数据库性能指标 2005-04-06 19:36:14(转载)
  13. c++中assert
  14. github进不去_app.gitbook.com进不去,一直卡着怎么回事
  15. 《Web程序设计》学习笔记1——web基础知识简述
  16. c语言实现按键的抖动与消除,7.3 按键消抖
  17. 联想电脑摄像头无法使用
  18. 谷尼国际软件-企业竞争情报系统
  19. 机器学习梯度消失,梯度爆炸原因
  20. 渗透测试之信息收集总结

热门文章

  1. 作业调度系统--SGE和PBS的使用方法
  2. poj1753Flip Game
  3. 双十一苏宁“狮晚”PK天猫“猫晚”,玩的是娱乐,赢的是流量
  4. 下载视频并保存至手机相册
  5. 一个近乎完美的Unity全平台原生c#热更方案
  6. Retinanet训练自己的数据(1):数据准备
  7. 自动化测试平台及可视化界面
  8. 利用Html与css从零开始制作基础静态网页(web课设)
  9. IPO并不遥远,飞哥IPERi模型助你打开互联网创业创新成功密码
  10. 查看linux当前屏保文件夹,linux下屏保设置