4 SODA for Cのキャラクタ・セットに関する考慮事項
SODA for Cでのキャラクタ・セットの使用について説明します。これは、JSON文書のエンコーディングにのみ適用されます。(JSON以外のドキュメントは常にBLOB
コンテンツを使用してSODAコレクションに格納されますが、文字ではなく一連のバイトとしてのみ扱われます。)
JSONデータ用のSODA for Cおよびキャラクタ・セット・エンコーディング: クライアントとデータベース
SODA for Cには、クライアント側とデータベースの2種類のJSONデータ・キャラクタ・セット・エンコーディングが含まれます。
JSONを定義する標準では、JSONデータはUnicodeキャラクタ・セットでエンコードされます。つまり、JSONデータは、定義上はUnicodeデータです。しかしクライアント側では、SODA for Cは、JSONデータがUnicodeである必要があるという制限を緩和し、他のエンコーディングを持つがそれ以外の場合はJSON構文を含んだデータを使用できます。
クライアント側:
-
SODA for Cクライアントで使用できるUnicode以外のエンコーディングは、EBCDICを除いて、Oracle Call Interface (OCI)により許可されているすべてのエンコーディングです。EBCDICキャラクタ・セットはSODAドキュメントには使用できません。
-
SODA for Cクライアントで使用できるUnicodeエンコーディングは、UTF-8、UTF-16 LE (リトル・エンディアン)、UTF-16 BE (ビッグ・エンディアン)です。これらは、それぞれOracle Databaseのキャラクタ・セットAL32UTF8、AL32UTF16およびAL32UTF16LEに対応しています。UTF-32を使用することはできません - これはOCIクライアント側のエンコーディングではありません。
データベース側(つまり、コレクションのコンテンツ列):
-
データベース・キャラクタ・セットとして、Unicode UTF-8が実装されるAL32UTF8を使用することをお薦めします。
-
コレクション内のコンテンツ列のJSONデータに使用されるエンコーディングは、SQLタイプにより決まります。
-
VARCHAR2
- ドキュメントはAL32UTF8としてエンコードされます。VARCHAR2
データは、常にデータベース・キャラクタ・セットに格納されます。 -
BLOB
- ドキュメントはUTF-8、UTF-16 BEまたはUTF-16 LEとしてエンコードされます。これらのUnicodeエンコーディングのどれが使用されるかは、クライアントからデータベースへのJSONドキュメントの書込みで説明されているように、入力ドキュメントがクライアント側でどのようにエンコードされたかによって決まります。 -
CLOB
- ドキュメントはUCS-2としてエンコードされます。CLOB
インスタンスは、データベース・キャラクタ・セットが(AL32UTF8のように)マルチバイトの場合は常に、UCS-2としてエンコードされます。
-
クライアント側とデータベース側のエンコーディングが同じ(どちらもUnicode)である場合、相互の変換は必要ありません。
しかしこれらが異なる場合、SODAは自動的に一方のキャラクタ・セットからもう一方のキャラクタ・セットに変換します。クライアント側のドキュメントで使用されている文字に対応するUnicode文字がない場合、ドキュメントの書込み時のデータベース・キャラクタ・セットへの変換は情報の損失を伴います。同様に、データベース側のドキュメントで使用されている文字にクライアント側のキャラクタ・セットで対応する文字がない場合、ドキュメントの読取り時の変換は情報の損失です。
次に例を示します。
-
クライアント側のエンコーディングがJA16SJISであり、SODAコレクションのコンテンツ列がSQLデータ型
VARCHAR2
を使用してJSONデータを格納するように構成されているとします。コレクションにデータを書き込むと、SODAは自動的にJA16SJISからデータベース・キャラクタ・セット(AL32UTF8)に変換します。 -
クライアント側のエンコーディングがAL16UTF16LEであり、コレクションがSQLデータ型
BLOB
を使用してJSONデータを格納するように構成されているとします。データ型BLOB
はAL16UTF16LEのエンコードをサポートしているため、変換は必要ありません。
デフォルトでは、OCIで使用されるキャラクタ・セットは環境変数NLS_LANG
によって定義されます。指定されたOCIクライアントに対して、OCI関数OCIEnvNlsCreate()
をパラメータcharset
を使用して、この設定をオーバーライドできます。
特に、OCIEnvNlsCreate()
を使用して、指定されたクライアントによって使用されるキャラクタ・セットをOCI_UTF16ID
(UTF-16)として定義する環境ハンドルを作成できます。これはNLS_LANG
からは設定できません。キャラクタ・セットOCI_UTF16ID
は、エンディアン(ビッグ・エンディアンまたはリトル・エンディアン)がクライアントの実行されるプラットフォームによって異なるUTF-16エンコーディングを指定します。
ドキュメントがクライアント・アプリケーションからデータベースに書き込まれるか、ドキュメントがデータベースからクライアント・アプリケーションに読み取られると、アプリケーションはドキュメントでどのようなクライアント側エンコーディングを使用するかをOCIに通知します。これは、パラメータdocFlags
によって実行されます。このパラメータは、ドキュメント・ハンドル作成関数またはドキュメント・ハンドルを提供せずにドキュメントにコンテンツを書き込むための簡易関数のいずれかに渡されます。つまり、パラメータdocFlags
はクライアント側のドキュメントのエンコーディングを制御します。
クライアントからデータベースへのJSONドキュメントの書込み
ドキュメント・ハンドルを作成するSODA for Cの関数には、接頭辞OCISodaDocCreate
を含んだ名前が付いています。それらはすべて、パラメータdocFlags
を受け入れます。
SODA for Cはまた、ドキュメント・ハンドルを提供せずにJSONコンテンツをデータベースに書き込むための簡易関数も提供します。これらの関数には、接尾辞WithCtnt
("with content"「コンテンツ付き」の略)を含んだ名前が付いています。これらもまた、パラメータdocflags
を受け入れます。
書込み用に、パラメータdocFlags
は次の値のいずれかを指定できます。
-
OCI_DEFAULT
- 環境ハンドル、または環境変数NLS_LANG
(ハンドルに設定されていない場合)によって設定されたキャラクタ・セットを使用します。環境ハンドルまたは
NLS_LANG
で指定されたエンコーディングでドキュメント・コンテンツを供給する必要があります。それ以外の場合、書込み操作の結果は予測できません。キャラクタ・セットは、EBCDICを除き、OCI (Unicodeまたは非Unicode)に有効な任意のキャラクタ・セットです。(OCI_UTF16の場合は、エンディアンがクライアントの実行されているプラットフォームのエンディアンと一致するUTF-16エンコーディングでドキュメントを供給する必要があります。)
OCI_DEFAULT
を使用して、UnicodeとしてエンコードされていないドキュメントをBLOB
列に書き込むと、SODAはコンテンツを書き出す前にUTF-8に変換します。 -
OCI_SODA_DETECT_JSON_ENC
- UTF-8、UTF-16 LE (リトル・エンディアン)、またはUTF-16 BE (ビッグ・エンディアン)として、ドキュメント・コンテンツのエンコーディングを自動的に検出します。これらのいずれかのエンコーディングでドキュメント・コンテンツを提供する必要があります。それ以外の場合、書込み操作の結果は予測できません。
クライアント側でJSONデータを処理するための使用事例:
-
非Unicodeエンコーディングまたは単一のUnicodeエンコーディングで作業するには、
OCI_DEFAULT
を使用します。 -
同じアプリケーション内でUnicodeエンコーディング(UTF-8、UTF-16 LE、UTF-16 BE)の組合せで作業するには、
OCI_SODA_DETECT_JSON_ENC
を使用します。(OCI_DEFAULT
では、ドキュメントは環境ハンドルまたはNLS_LANG
によって指定された単一のエンコーディングであるとみなされます。) -
クライアント側のプラットフォームとは異なるエンディアンを持つUTF-16エンコーディングで作業するには、
OCI_SODA_DETECT_JSON_ENC
を使用します。
クライアント側のキャラクタ・セットがデータベース内のコンテンツ列のキャラクタ・セットと異なる場合、SODAは書込み時にそのドキュメントをコンテンツ列のキャラクタ・セットに変換します。このような変換を回避するには、コンテンツ・データ型としてBLOB
を使用し(BLOB
がデフォルト)、エンコーディングUTF-8またはUTF-16 (BEまたはLE)エンコーディングでコンテンツを指定します。こうすると、パラメータのdocFlags
にどの値(OCI_DEFAULT
またはOCI_SODA_DETECT_JSON_ENC
)を使用するかは関係ありません。
データベースからクライアントへのJSONドキュメントの読取り
クライアント側のドキュメントにコンテンツを読み取るSODA for C関数(OCISodaFindOneWithKey()
など)は、取得されたコンテンツに使用するクライアント側のエンコーデイングの指定に使用するパラメータdocFlags
も提供します。
読取り用に、パラメータdocFlags
は次の値のいずれでも指定できます。
-
OCI_DEFAULT
- 環境ハンドル、または環境変数NLS_LANG
(ハンドルに設定されていない場合)によって設定されたキャラクタ・セットを使用します。(これは、データベースへのドキュメントの書込みの場合と同じです。) -
OCI_SODA_AS_STORED
- データベースに格納するためと同じエンコーディングを使用します。この値はBLOB
ストレージを使用するコレクション用の場合にのみ有効です。それ以外の場合、エラーが発生します。 -
OCI_SODA_AS_AL32UTF8
- UTF-8エンコーディングを使用します。
クライアント側キャラクタ・セットが、データベース内のコンテンツ列のキャラクタ・セットと異なる場合、SODAは読取り時にドキュメントをクライアント用に指定されたキャラクタ・セットに変換しますこのような変換を回避するには、コンテンツ・データ型としてBLOB
を使用し(BLOB
がデフォルト)、パラメータdocFlags
にOCI_SODA_AS_STORED
を使用します。
関連項目:
-
OCIクライアント・キャラクタ・セットの設定の詳細は、Oracle Call Interfaceプログラマーズ・ガイドを参照
-
グローバリゼーションに対するOCIサポートの詳細は、Oracle Call Interfaceプログラマーズ・ガイドを参照
-
Oracle Databaseのグローバリゼーション・サポートの詳細は、Oracle Databaseグローバリゼーション・サポート・ガイドを参照
-
Unicodeについては、Unicode.orgを参照
-
JSONデータ交換フォーマットについては、IETF RFC4627およびECMA404を参照