暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

聊聊Oracle数据库字符集

扫地僧的故事 2020-07-07
757
最近领导给我安排了一个美差,去机房盯着小哥们布线。于是,我就有了大把的学习时间,可以自己慢慢倒腾了。
本来是打算继续第一篇没完成的mysql备份工具介绍(拖延症晚期患者。。。),或者写写最近学习C语言过程中的一些感悟和收获。
但是一大早就收到一个朋友的反馈,说我上一篇字符集问题讲得不太清楚,客户端,服务端和终端的概念模糊,他的理解是:终端就是客户端。
所以,我就再做个小实验来说明一下,终端只是决定会不会正确显示汉字,而不会决定字符集的对错。字符集的问题,本质上和终端是没有关系的。NLS_LANG的设置才是真正决定插入数据库的汉字的编码格式。
我的实验环境:数据库字符集为AL32UTF8。然后用proc写了一段demo,proc程序里的"中"字,是utf8编码的,即,0xE4B8AD。如下:
demo1.pc:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<sqlca.h>


    /*save as UTF8*/
    void sql_error(char *);


    void sql_error(char *msg)
    {
    printf("\n%s,%ld,%s\n", msg,sqlca.sqlcode,(char *)sqlca.sqlerrm.sqlerrmc);
    EXEC SQL ROLLBACK RELEASE;
    exit(-1);
    }


    void main()
    {
    char v1[60];
    char *username="scott";
    char *password="tiger";
    char c[4] = {0xE4,0xB8,0xAD,0};
    EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE ERROR: ");
    EXEC SQL CONNECT :username IDENTIFIED BY :password;
    EXEC SQL delete from t1;
    EXEC SQL insert into t1 (c1) values(:c);
    EXEC SQL select c1 into :v1 from t1 where rownum<2;
    EXEC SQL COMMIT RELEASE;
    printf("c1: %s \n", v1);
    }
    编译:
      proc demo1.pc
      gcc -o demo1 demo1.c -I$ORACLE_HOME/precomp/public -L$ORACLE_HOME/lib -lclntsh
       执行:
        [oracle@rac112 charset]$ export NLS_LANG=american_america.AL32UTF8
        [oracle@rac112 charset]$ ./demo1
        c1:
        [oracle@rac112 charset]$ export NLS_LANG=american_america.ZHS16GBK
        [oracle@rac112 charset]$ ./demo1
        c1:
        如果觉得还有疑问,那我把代码改成这样的,再品品?
        demo2.pc
          #include<stdio.h>
          #include<string.h>
          #include<stdlib.h>
          #include<sqlca.h>


          /*save as UTF8*/
          void sql_error(char *);


          void sql_error(char *msg)
          {
          printf("\n%s,%ld,%s\n", msg,sqlca.sqlcode,(char *)sqlca.sqlerrm.sqlerrmc);
          EXEC SQL ROLLBACK RELEASE;
          exit(-1);
          }


          void main()
          {
          char v1[60];
          char *tmp="中" ;
          char *username="scott";
          char *password="tiger";
          char c[4];
          memcpy(c,tmp,strlen(tmp));
          EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE ERROR: ");
          EXEC SQL CONNECT :username IDENTIFIED BY :password;
          EXEC SQL delete from t1;
          EXEC SQL insert into t1 (c1) values(:c);
          EXEC SQL select c1 into :v1 from t1 where rownum<2;
          EXEC SQL COMMIT RELEASE;
          printf("c1: %s \n", v1);
          }
          编译:
            proc demo2.pc
            gcc -o demo2 demo2.c -I$ORACLE_HOME/precomp/public -L$ORACLE_HOME/lib -lclntsh
             执行:
              [oracle@rac112 charset]$ export NLS_LANG=american_america.AL32UTF8
              [oracle@rac112 charset]$ ./demo2
              c1:
              [oracle@rac112 charset]$ export NLS_LANG=american_america.ZHS16GBK
              [oracle@rac112 charset]$ ./demo2
              c1:

              看了这两个实验,应该很容易就能理解oracle数据库是如何处理字符集了吧?
              总结:在Oracle数据库中,当NLS_LANG设置的编码格式,与程序中的中文汉字编码格式不一致时,就会出现乱码。
              字符集的问题暂时告一段落啦,再说下去我自己都要烦了。

              最后再附上一张美女图吧,感谢大家翻到最后!


              美女图真的太难找了,好怕被告侵权啥的,以后可能就没有啦,只能给大家找点风景图来净化净化眼睛和心灵~


              最后修改时间:2020-07-07 11:16:32
              文章转载自扫地僧的故事,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论