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がデフォルト)、パラメータdocFlagsOCI_SODA_AS_STOREDを使用します。

関連項目: