【Oracle】Oracle文字セットを徹底的に理解する
基本概念文字セット(Charcter set):システムでサポートされているすべての抽象文字の集合です。文字は各種の文字と記号の総称で、各国の文字、句読点、図形記号、数字などを含みます。一般的な文字セットはASCII、ZHS 16 GB 231280、ZHS 16 GBKなどがあります。文字コード(Charcter Encocding)は、この法則を用いて自然言語の文字の集合(アルファベットや音節表など)を、他の集合(コンピュータコードなど)と対応付けることができるという法則です。すなわち、シンボルセットとデジタルシステムとの間に対応関係を確立する。文字セットに対応して、一般的な文字コードはASCi、ZHS 16 GBK、ZHT 16 BIG 5、ZHS 32 GB 18030などである。文字セットの定義は文字のセットですが、文字コードとはどのようにしてこれらの文字をバイトにして保存、読み込み、転送に使いますか?万国コード(Unicode):ほぼ人間のすべての利用可能な文字が含まれていますが、毎年増え続けています。これは全世界のすべての文字を統一化して、統一コード化して、文字の互換性と文字の変換の問題がもう現れません。これは次の3つの符号化方式があります。1.UTF-32符号化:4バイトを固定して1文字を表します。空間利用効率の問題があります。2.UTF-16符号化:比較的一般的な60000文字に対して、2バイトを使用して符号化し、残りは4バイトを使用する。3.UTF-8コード:ASCIIコードに対応しています。ラテン語、ギリシャ語などは二バイトを使います。漢字を含む他の常用文字は3バイトを使います。残りの少ない使用文字は4バイトを使用します。Oracle文字セットの基本原理は、Oracle文字セットの基本原理を理解する前に、必ず以下の3つの概念を明確にする必要があります。
シーン1:セッション1挿入、セッション1クエリ、データベースにエラーを格納しますが、表示は正しいです。挿入プロセス:「中国」「クライアント操作システムの文字セットZHS 16 GBKにおけるコードは」d 6,d 0,b 9,fa「NLS_のために」LANGはデータベースの文字セットと同じで、データベース端でクライアントから送られてきた文字コードをそのままデータベースに保存しないため、データベースに格納されているコードも「d 6,d 0,b 9,fa」です。読み取りプロセス:データベース端で読み取られたコードは「d 6,d 0,b 9,fa」です。NLS_のためです。LANGはデータベースの文字セットと同じで、クライアントがデータベースの端から送られてきた文字コードに対しては、変換を行わずに直接表示し、コード化した」d 6,d 0,b 9,fa「クライアント操作システムの文字セットで、ZHS 16 GBKに対応する漢字は「中国」です。以上の分析から分かるように、正しく読んでいますが、負の負がプラスになっていますので、実際にデータベースに保存されているのは間違いです。この場合は特に注意してください。これをlength操作すれば簡単に仮面が開くことができます。
シーン2:セッション1挿入、セッション2クエリ、データベースにエラーを格納し、表示もエラーです。挿入プロセスはシーン1と同じです。ここでは疲れません。読み取りプロセス:データベース端で読み取られた符号は「d 6,d 0,b 9,fa」である。LANGはデータベースの文字セットと違って、クライアントがデータベースの端から送られてきた文字コードを変換します。データベースの端の文字セットAL 32 UTF 8に「d 6、d 0、b 9、fa」を作成しました。クライアント操作システムの文字セットZHS 16 GBKに対応するコードが見つけられないので、使うしかないですか?代わりに。
シーン3:session 2挿入、session 1クエリーは、データベースに正しく格納されていますが、エラーが表示されます。挿入プロセス:「中国」「クライアント操作システムの文字セットZHS 16 GBKにおけるコードは」d 6,d 0,b 9,fa「NLS_のために」LANGはデータベースの文字セットと違って、Oracleは文字コード変換を行います。つまり、文字セットZHS 16 GBKの「中国」のコード「d 6,d 0,b 9,fa」を文字セットに変換します。読み取りプロセス:データベース端で読み取られたコードは”e 4,b 8,ad,e 5,9 b,bd”であり、NLS_のために。LANGはデータベースの文字セットと同じです。クライアントはデータベースの端から送られてきた文字コードを直接に表示しません。「e 4、b 8、ad、e 5、9 b、bd」はクライアント操作システムの文字セットZHS 16 GBKに対応する漢字は「ちょろちょろ」です。 健保ㄔ本の2文字は、現在は3文字になりました。ZHS 16 GBKの漢字は2バイトで符号化されていますので。
シーン4:session 2挿入、session 2クエリ、データベースに正しく格納され、表示も正しいです。挿入プロセスとシーン3は似ています。読み取りプロセス:データベース端で読み取られたコードは”e 4,b 8,ad,e 5,9 b,bd”であり、NLS_のために。LANGとデータベースの文字セットは違って、クライアントはデータベースの端から送られてきた文字コードを変換して、データベースの端の文字セットAL 32 UTF 8里、中国の「二文字のコード」e 4、b 8、ad、e 5、9 b、bd「クライアント操作システムの文字セットZHS 16 GBKに変換して、「中国」の二文字の符号化「d 6、d 0、b 9、fa」を正常に表示します。このような状況は二回にわたって転換されましたが、最も正確で、最もおすすめの方法です。付録:Oracle文字セットのオーバーセットとサブセットの対応関係は、http://download.oracle.com/docs/cd/B19306_01/server.1.102/b 14225/appocaledca.httm菵sthref 1988結論:NLS_LANGは、クライアントオペレーティングシステムの文字セットとのみ関連しており、クライアントオペレーティングシステムの文字セットとデータベース文字セットとの間で正確に変換できない場合、まず、クライアント端末の文字セットを変更すべきであり、NLS_を簡単に変換するのではない。LANGはデータベースの文字セットと同じに設定します。
SQL> select * from v$nls_parameters where parameter='NLS_CHARACTERSET';
PARAMETER VALUE
------------------------------ -----------------
NLS_CHARACTERSET AL32UTF8
2.クライアントオペレーティングシステムの文字セット、すなわちクライアントオペレーティングシステムは、どの文字で記憶文字をエンコードしますか?Windowsであれば、コードページをchcpコマンドで取得することができます。
C:\Users\xianzhu>chcp
Active code page: 936
はこのコードページに基づいて、マイクロソフトの公式文書「National Language Support(NLS)API Reference」に対応する文字セットを見つけました。Linuxであれば、文字セットは/etc/syssconfig/i 18 nに設定されます。
LANG="zh_CN.GB2312" ( )
SUPPORTED="zh_CN.GB2312"( )
SYSFONT="lat0-sun16"( )
3.クライアントNLS_LANGパラメータ:Oracleにクライアントオペレーティングシステムの文字セットを指示するためのパラメータです。以上の3つの基本概念があったら、Oracle文字セットの変換の基本原則を述べます。1.クライアントのNLS_を設定します。LANGはクライアントオペレーティングシステムの文字セット2です。データベース文字セットがNLS_に等しい場合LANGは、データベースとクライアントが文字を転送する時には何の変換もしません。3.それらが異なる場合は、異なる文字セット間で変換する必要があります。クライアントオペレーティングシステムの文字セットだけがデータベースの文字セットに基づいて正確に変換できます。でないと、文字化けが発生します。いくつかのよくある情況は次の例を分析して、更に現象を通して本質を見て、私達はこの例に対して分析を行います。この例は、
1. Unicode(UTF-8 )
10.2.0.4.0, :
SQL> select * from v$nls_parameters where parameter='NLS_CHARACTERSET';
PARAMETER VALUE
---------------------------------------- ------------------------------
NLS_CHARACTERSET AL32UTF8
2. 936( ZHS16GBK)
chcp windows (code page)
C:\Documents and Settings\a105024\Desktop>chcp
Active code page: 936
3.
SQL> create table test(id number,var varchar2(30));
Table created.
4.
session,session1 NLS_LANG ( AL32UTF8):
C:\Documents and Settings\a105024\Desktop>set nls_lang=Simplified Chinese_China.AL32UTF8
:
Session_1>insert into test values(1,' ');
1 row created.
Session_1>commit;
Commit complete.
session2 NLS_LANG ( ZHS16GBK):
C:\Documents and Settings\a105024\Desktop>set nls_lang=Simplified Chinese_China.ZHS16GBK
:
Session_2>insert into test values(2,' ');
1 row created.
Session_2>commit;
Commit complete.
5.
session 1 :
Session_1>select * from test;
ID VAR
---------- ---------------------
1
2
session 2 :
Session_2>select * from test;
ID VAR
---------- --------------------
1 ???
2
上の例が怪しいように見えますが、session 1と2は自分が挿入した文字列を正常に表示し、相手が挿入した文字列を正常に表示することができません。はっきりさせるためには、まずデータベースにこの2つの文字列がどのように格納されているかを知る必要があります。私達はdump関数を使って文字のデータベースでのコードを得ることができます。
SQL> select id,dump(var,1016) from test;
ID DUMP(VAR,1016)
-- ------------------------------------------------------------
1 Typ=1 Len=4 CharacterSet=AL32UTF8: d6,d0,b9,fa
2 Typ=1 Len=6 CharacterSet=AL32UTF8: e4,b8,ad,e5,9b,bd
はAL 32 UTF 8の符号化に基づいて、「中国」の2文字の正しい符号化は(いずれも3バイト)です。中--e 4,b 8,ad国--e 5,9 b,bdです。だからsession 1が挿入した文字列はデータベースでの符号化が間違っています。session 2は正しいです。これもなぜNLS_を設置しなければならないのですか?LANGはクライアント操作システムの文字セットです。しかし、上記の実験によって、データベースに正確に保存されており、クライアントが正常に表示されるとは限らないことが分かります。同様に、インスタントデータベースが正しく記憶されていないため、クライアントが正常に表示されることがある。焦らないでください。ゆっくり話してください。シーン1:セッション1挿入、セッション1クエリ、データベースにエラーを格納しますが、表示は正しいです。挿入プロセス:「中国」「クライアント操作システムの文字セットZHS 16 GBKにおけるコードは」d 6,d 0,b 9,fa「NLS_のために」LANGはデータベースの文字セットと同じで、データベース端でクライアントから送られてきた文字コードをそのままデータベースに保存しないため、データベースに格納されているコードも「d 6,d 0,b 9,fa」です。読み取りプロセス:データベース端で読み取られたコードは「d 6,d 0,b 9,fa」です。NLS_のためです。LANGはデータベースの文字セットと同じで、クライアントがデータベースの端から送られてきた文字コードに対しては、変換を行わずに直接表示し、コード化した」d 6,d 0,b 9,fa「クライアント操作システムの文字セットで、ZHS 16 GBKに対応する漢字は「中国」です。以上の分析から分かるように、正しく読んでいますが、負の負がプラスになっていますので、実際にデータベースに保存されているのは間違いです。この場合は特に注意してください。これをlength操作すれば簡単に仮面が開くことができます。
Session_1>select length(var) from test where id=1;
LENGTH(VAR)
-----------
3
の長さはなんと3です。実際の長さは2だけです。これは多くの迷惑をかけます。シーン2:セッション1挿入、セッション2クエリ、データベースにエラーを格納し、表示もエラーです。挿入プロセスはシーン1と同じです。ここでは疲れません。読み取りプロセス:データベース端で読み取られた符号は「d 6,d 0,b 9,fa」である。LANGはデータベースの文字セットと違って、クライアントがデータベースの端から送られてきた文字コードを変換します。データベースの端の文字セットAL 32 UTF 8に「d 6、d 0、b 9、fa」を作成しました。クライアント操作システムの文字セットZHS 16 GBKに対応するコードが見つけられないので、使うしかないですか?代わりに。
シーン3:session 2挿入、session 1クエリーは、データベースに正しく格納されていますが、エラーが表示されます。挿入プロセス:「中国」「クライアント操作システムの文字セットZHS 16 GBKにおけるコードは」d 6,d 0,b 9,fa「NLS_のために」LANGはデータベースの文字セットと違って、Oracleは文字コード変換を行います。つまり、文字セットZHS 16 GBKの「中国」のコード「d 6,d 0,b 9,fa」を文字セットに変換します。読み取りプロセス:データベース端で読み取られたコードは”e 4,b 8,ad,e 5,9 b,bd”であり、NLS_のために。LANGはデータベースの文字セットと同じです。クライアントはデータベースの端から送られてきた文字コードを直接に表示しません。「e 4、b 8、ad、e 5、9 b、bd」はクライアント操作システムの文字セットZHS 16 GBKに対応する漢字は「ちょろちょろ」です。 健保ㄔ本の2文字は、現在は3文字になりました。ZHS 16 GBKの漢字は2バイトで符号化されていますので。
シーン4:session 2挿入、session 2クエリ、データベースに正しく格納され、表示も正しいです。挿入プロセスとシーン3は似ています。読み取りプロセス:データベース端で読み取られたコードは”e 4,b 8,ad,e 5,9 b,bd”であり、NLS_のために。LANGとデータベースの文字セットは違って、クライアントはデータベースの端から送られてきた文字コードを変換して、データベースの端の文字セットAL 32 UTF 8里、中国の「二文字のコード」e 4、b 8、ad、e 5、9 b、bd「クライアント操作システムの文字セットZHS 16 GBKに変換して、「中国」の二文字の符号化「d 6、d 0、b 9、fa」を正常に表示します。このような状況は二回にわたって転換されましたが、最も正確で、最もおすすめの方法です。付録:Oracle文字セットのオーバーセットとサブセットの対応関係は、http://download.oracle.com/docs/cd/B19306_01/server.1.102/b 14225/appocaledca.httm菵sthref 1988結論:NLS_LANGは、クライアントオペレーティングシステムの文字セットとのみ関連しており、クライアントオペレーティングシステムの文字セットとデータベース文字セットとの間で正確に変換できない場合、まず、クライアント端末の文字セットを変更すべきであり、NLS_を簡単に変換するのではない。LANGはデータベースの文字セットと同じに設定します。