• 转://oracle字符集


    一、oracle字符集基础知识
    oracle数据库有国家字符集(national character set)与数据库字符集(database character set)之分。两者都是在创建数据库时需要设置的。国家字符集主要是用于nchar、nvarchar、nclob类型的字段数据,而数据库字符集使用很广泛,它用于:char、varchar、clob、long类型的字段数据;

    oracle的字符集名字一般由以下部分组成:语言或区域、表示一个字符的比特位数、标准字符集名称(可选项,s或c,表示服务器或客户端)。oracle字符集utf8与utfe不符合此规定,其它基本都是这种格式。nls_lang=<language>_<territory>.<clients characterset>,如:
    us7ascii:表示区域是us,用7个比特位表示一个字符,标准的字符集名称为ascii
    zhs16gbk:表示简体中文(zht为繁体中文),一个字符需要16位比特,标准的字符集名称为gbk
    zhs16cgb231280:表示简体中文,一个字符需要16位比特,标准的字符集名称为gb231280
    备注:
    1、nls( national language support)国家语言支持
    2、gbk编码标准是gb2312编码标准的扩展,但数据库字符集zhs16gbk与zhs16cgb231280之间却不是严格的超集与子集的关系,主要是有些汉字的编码在两个字符集中的数值是不同的,因此它们进行字符集转换时会出现问题。
    /*Oracle数据库最早支持的编码方案是US7ASCII。Oracle的字符集命名遵循以下命名规则:<Language><bitsize><encoding> 即: <语言><比特位数><编码> 。比如: AL32UTF8表示:AL,代表all,指使用所有语言;32,,32位;UTF8编码。查看环境变量发现:NLS_LANG=American_America.AL32UTF8,American表示语言;America表示地区;AL32UTF8字符集类型*/

    二、查看字符集参数
    nls_characterset:字符集;nls_nchar_characterset:国家字符集
    数据库可用字符集参数:v$nls_valid_values
    数据库实例字符集环境:nls_instance_parameters
    数据库服务器字符集:nls_database_parameters(其来源于props$)
    会话字符集环境:nls_session_parameters:表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如会话无特殊设置,将与v$nls_parameters一致。
    v$nls_parameters 或 userenv('language'):表示当前字符集环境。如在客户端执行,则表示客户端字符集环境。

    查看客户端字符集:
    ---linux或unix平台(须设置了nls_lang,否则是空值)
    $ env | grep nls_lang
    $ echo $nls_lang
    ---windows平台
    echo %nls_lang% (须设置了nls_lang,否则是空值)
    或 查看注册表

    设置客户端字符集
    ---linux或unix平台
    export nls_lang=american_america.utf8
    或加入到.profile
    export nls_lang="simplified chinese_china.zhs16gbk"
    ---windows平台
    set nls_lang=simplified chinese_china.zhs16gbk
    set nls_lang=simplified chinese_america.utf8
    set nls_lang=american_america.utf8
    或修改注册表

    客户端的字符集要求与服务器一致,才能正确显示数据库的非ascii字符。如果多个设置存在的时候,优先级关系为:sql function >alter session>环境变量>注册表>参数文件 字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是american_america.zhs16gbk

    三、修改数据库字符集
    数据库字符集在创建后原则上不能更改。因此,在前期规划和安装之初考虑使用哪一种字符集十分重要。对数据库服务器而言,错误的修改字符集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改之前一定要确认两种字符集是否存在子集和超集的关系。一般来说,除非万不得已,我们不建议修改oracle数据库server端的字符集。
    有两种方法修改数据库字符集设置
    1. 通常需要导出数据库数据,重建数据库,然后再导入数据库数据的方式来转换。
    2. 通过alter database character set语句修改字符集,但创建数据库后可以修改的字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如utf8是us7ascii的超集,修改数据库字符集可使用alter database character set utf8。
    特别说明,我们最常用的两种字符集zhs16gbk和zhs16cgb231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持修改
    关于数据库子集-超级对照表(subset-superset pairs),可以参考官方文档

    sql>shutdown immediate;
    sql>startup mount;
    sql>alter system enable restricted session;
    9: sql>alter system set job_queue_processes=0;
    sql>alter system set aq_tm_processes=0;
    sql>alter database open;
    --从子集到父集
    sql>alter database character set zhs16gbk;
    --如果是从父集到子集,需要使用internal_use参数,跳过超子集检测
    sql>alter database national character set utf8;
    --sql>alter database national character set internal_use utf8;
    sql>shutdown immediate;
    sql>startup;
    如:alter database national character set utf8;
    有可能会出现ora-12717: cannot alter database national character set when nclob data exists 这样的提示信息.这时你用alter database national character set internal_use utf8;就可解决上述问题。

    四、案例
    1、问题:
    一个汉字用GBK存放是2个字符,用AL32UTF8占用3个字符,问题来了:一个字段A varchar2(10)存放了5个汉字,但是存放AL32UTF8的只能存放3个,所以在由ZHS16GBK字符集编码的数据库导出的DMP文件导入到由AL32UTF8字符集编码的数据库时有的表就会提示"字符过长",导入不成功!
    2、解决办法:源库是ZHS16GBK字符集,目标库是AL32UTF8,目标库要改字符集
    startup mount
    alter session set sql_trace=true;
    alter system enable restricted session;
    alter system set job_queue_processes=0;
    alter system set aq_tm_processes=0;
    alter database open;
    alter database character setzhs16gbk;
    ora-12712: new character set must be a superset of old characterset
    错误提示:新字符集必须为旧字符集的超集,这时我们可以跳过超集的检查做更改:
    alter database character set internal_use zhs16gbk; //跳过超子集检测
    ---alter database national character set internal zhs16gbk;国家字符集一般不修改
    alter session set sql_trace=false;
    select * from v$nls_parameters;
    shutdown immediate;
    startup
    select userenv('language') nls_lang from dual;

    #################################################
    附:
    1.更改数据库字符集为GBK
    SHUTDOWN IMMEDIATE;
    STARTUP MOUNT EXCLUSIVE;
    ALTER SYSTEM ENABLE RESTRICTED SESSION;
    ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
    ALTER SYSTEM SET AQ_TM_PROCESSES=0;
    ALTER DATABASE OPEN;
    ALTER DATABASE NATIONAL CHARACTER SET AL16UTF16; 更改国际字符集
    ALTER DATABASE CHARACTER SET ZHS16GBK; 更改本地字符集
    SHUTDOWN IMMEDIATE;
    STARTUP ;

    -- ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8;
    -- alter database character set internal_use ZHS16GBK ;
    -- ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE ZHS16GBK;

    2.如果错误信息,请对照一下信息
    如果提示:
    ORA-12717: Cannot issue ALTER DATABASE NATIONAL CHARACTER SET when NCLOB, NCHAR
    or NVARCHAR2 data exists
    则更改使用以下语句:
    ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE AL16UTF16;

    如果提示:
    ORA-12712: new character set must be a superset of old character set
    则更改使用以下语句:
    ALTER DATABASE character set INTERNAL_USE ZHS16GBK;

    如果提示:
    ORA-12721: operation cannot execute when other sessions are active
    则更改使用以下语句:
    SHUTDOWN IMMEDIATE;
    STARTUP MOUNT EXCLUSIVE;

    如果提示:
    ORA-01109: database not open
    则更改使用以下语句:
    ALTER DATABASE OPEN;

    如果提示:
    ORA-12719: operation requires database is in RESTRICTED mode
    则更改使用以下语句:
    ALTER SYSTEM ENABLE RESTRICTED SESSION;

  • 相关阅读:
    java 面向对象(十八):包装类的使用
    java 面向对象(十七):单元测试方法
    rxjava2学习
    多线程-wait(),notify(),notifyAll()
    多线程-Thread.join()的运用
    66. Plus One
    理解Android View的事件传递机制
    78. Subsets
    程序员学习与成长的方法(转发)
    android查询天气demo,基于mvp+kotlin+rxjava2+retrofit2
  • 原文地址:https://www.cnblogs.com/zfox2017/p/6651430.html
Copyright © 2020-2023  润新知