zoukankan      html  css  js  c++  java
  • 警示:AL32UTF8字符集不是ZHS16GBK字符集的超集

    今天有客户向我咨询:数据库由ZHS16GBK字符集修改为AL32UTF8字符集,发现中文的数据中小部分出现乱码,客户认为AL32UTF8明明可以支持更多的文字,不应该出现这样的情况才对。
    从现象看,基本可以确认故障是字符集转换导致的,Oracle也强烈不建议做这种字符集转换的操作,幸好该客户的操作只是在一个测试环境中操作的。不过,之前也一直有个误区,我们都知道AL32UTF8是可以支持多国语言的字符集,对于中文字节存储占用空间比ZHS16GBK多,然后第一反应就认为AL32UTF8应该是ZHS16GBK的超集。而如果是绝对的超集,就不应该出现任何乱码的情况,可实际用户反馈的现象的确是有小部分出现乱码的情况,所以有必要在测试环境再次验证一下。

    1.首先我的库ZHS16GBK的字符集

    SQL> select userenv('language') from dual;
    
    USERENV('LANGUAGE')
    ----------------------------------------------------
    AMERICAN_AMERICA.ZHS16GBK
    

    2.尝试修改字符集为AL32UTF8
    直接尝试修改,会发现Oracle明确给出错误提示ORA-12712:新的字符集必须是旧字符集的超集。这就说明我们要改的AL32UTF8字符集并不是ZHS16GBK的超集。

    SQL> alter database character set al32utf8;
    alter database character set al32utf8
    *
    ERROR at line 1:
    ORA-12712: new character set must be a superset of old character set
    

    如果非要修改,可以加internal_use参数强制修改,而这样的操作,自然就很有可能会造成部分数据出现乱码:

    SQL> alter database character set internal_use al32utf8;
    
    Database altered.
    
    SQL> select userenv('language') from dual;
    
    USERENV('LANGUAGE')
    --------------------------------------------------------------------------------
    AMERICAN_AMERICA.AL32UTF8
    

    此时如果我们通过PL/SQL Developer工具连接到数据库,还会有这样的警告信息:

    而客户端是Windows,chcp结果是936,也就是ZHS16GBK,这也进一步说明了ZHS16GBK和AL32UTF8字符集的不同。

    同时实验还验证,如果数据库字符集本身是AL32UTF8,想修改成为ZHS16GBK字符集,也是一样的情况,需要加internal_use参数才可以转换,也就是说这种转换一样可能出现乱码,不过这个情况反倒好理解,也符合我们之前的认知,就不再赘述了。

  • 相关阅读:
    析构函数可以内联吗(可以,但不建议)
    auto_ptr
    Oracle Enterprise Linux 6.0配置本地yum
    标准C++输入输出和字符串类学习小程序集锦
    [转载]解决mysql“Access denied for user 'root'@'localhost'”
    [Linux网络编程学习笔记]套接字地址结构
    javascript基础
    java学习笔记14动态代理
    2013面试总结_01
    jquery实现复选框checkbox全选(完善)
  • 原文地址:https://www.cnblogs.com/jyzhao/p/8654412.html
Copyright © 2011-2022 走看看