25.1 JSONにおける生成の概要

JSONデータの生成の概要について説明します(ベスト・プラクティス、SQL/JSON生成関数、単純なJSONコンストラクタ構文、入力SQL値の処理、および生成されるデータ)。

データベースのJSON以外のデータからJSONデータを生成するための最適な方法は、SQLを使用する方法です。標準SQL/JSON関数json_objectjson_arrayjson_objectaggおよびjson_arrayaggは、このために設計されています。生成されるデータがJSON型の場合は、JSONデータ型のコンストラクタ関数JSONを使用することが便利な代替の方法です。

どちらの方法を使用しても、SQL問合せからJSONデータを直接簡単に作成できます。非JSONデータをJSONオブジェクトおよびJSON配列として表すことが可能になります。生成関数またはコンストラクタJSONへの呼出しをネストすると、複雑で階層化されたJSON文書を生成できます。ネストされた副問合せにより、1対多関係を表すJSONデータを生成できます。脚注1

非JSONデータからJSONデータを構成するための最適な方法

SQL/JSON生成関数の使用のかわりとなる方法は、エラーが発生しやすかったり、非効率的であることが一般的です。

  • 文字列の連結を使用したJSON文書の生成では、エラーが発生しやすくなります。特に、二重引用符(")などの特殊文字をいつ、どのようにエスケープするかという点について、順守する必要がある複雑なルールが多数あります。これらのルールは、見逃されたり誤って解釈されることが多く、その結果、正しくないJSONデータが生成される可能性が生じます。

  • 非JSONの結果セットをデータベースから読み取り、クライアント側のアプリケーション・コードを使用してJSONデータを生成する方法は、特にネットワーク・オーバーヘッドが原因で非常に効率が悪くなることが一般的です。1対多関係をJSONデータとして表す場合は、必要な非JSONデータをすべて収集するために、複数のSELECT操作が必要になることが多くなります。生成する文書で複数のレベルの1対多関係が示される場合は、この方法では必要なコストが増えることが考えられます。

SQL/JSON生成関数およびコンストラクタJSONでは、このような問題が発生しません。非JSONデータベース・データからJSONデータを構成するジョブ向けに設計されています。

  • これらの関数では、常に整形式のJSON文書が構成されます。

  • 関数でSQL副問合せを使用すると、1つのSQL文を使用してJSON文書一式を生成できるため、生成処理を最適化できます。

  • クライアントに戻されるのは、生成された文書だけなので、ネットワーク・オーバーヘッドは最小化されます。生成される文書当たり、多くても1往復で済みます。

SQL/JSONの生成関数

  • ファンクションjson_objectおよびjson_arrayは、それぞれJSONオブジェクトまたは配列を構成します。最も単純なケースでは、json_objectは引数としてSQL名前/値ペアを受け取り、json_arrayは引数としてSQL値を受け取ります。

  • 関数json_objectaggおよびjson_arrayaggは、集計のSQLファンクションです。これらの関数は、グループ化されたSQL問合せの行に格納された情報を、それぞれ、JSONオブジェクトと配列に変換します。引数の評価によって、オブジェクト・メンバーと配列要素の数が決まります。つまり、結果のサイズは現在の問合せ対象データを反映します。

    json_objectaggおよびjson_arrayaggの場合、オブジェクト・メンバーと配列要素の順序は、指定されません。json_arrayaggの場合、json_arrayaggの呼出し内でORDER BY句を使用すると、配列要素の順序を制御できます。

SQL/JSON生成関数によって戻される結果

デフォルトでは、生成されたJSONデータは生成関数からSQL VARCHAR2(4000)値として戻されます。オプションのRETURNING句を使用して、異なるVARCHAR2サイズを指定するか、かわりにJSONCLOBまたはBLOBの戻り値を指定できます。BLOBが戻り型の場合、文字セットはAL32UTF8です。

戻り型がJSONである場合を除き、入力SQL値から生成されるJSON値はテキストのJSONにシリアライズされます。このシリアライズは、SQL/JSONファンクションjson_serializeと同じ効果があります。

ノート:

SQL/JSONファンクションjson_serializeは、標準書式を使用して、Oracle JSON言語スカラー型(浮動小数点や日付など)の値を一貫してシリアライズします。

たとえば、ISO 8601日付書式YYYY-MM-DDを使用してJSON日付値をシリアライズします。

他の形式のJSON文字列値を含むテキストJSONオブジェクトまたは配列を生成する場合は、その形式の文字列を生成関数への入力として指定します。(json_serializeへの文字列入力は、そのまま出力されます。)

たとえば、json_objectで、異なるISO 8601日付書式の文字列フィールドを持つオブジェクトを生成する場合は、to_charなどのSQL変換関数を使用してその文字列を指定し、それをjson_objectに渡します。

SQL/JSON生成関数の入力値の処理

SQL/JSON生成関数は入力としてSQLの値を受け取り、返されるJSONオブジェクトまたは配列内にJSON値を生成します。出力に使用されるJSON値が入力値からどのように生成されるかは、それらのSQLデータ型によって異なります。「SQL/JSON生成関数の入力値の処理」を参照してください。

SQL/JSON生成関数のオプションの動作

オプションとして、SQL NULLを処理する句、RETURNING句およびキーワードSTRICTおよびWITH UNIQUE KEYSを指定できます。

  • NULLを処理する句—入力評価の結果のSQL NULL値をどのように扱うかを決定します。

    • NULL ON NULL— 入力のSQL NULL値が、出力のJSONオブジェクトまたは配列に含めるJSON nullに変換されます。これは、json_objectおよびjson_objectaggデフォルト動作です。

    • ABSENT ON NULL—入力のSQL NULL値の結果、対応する出力がない状態になります。これは、json_arrayおよびjson_arrayaggデフォルト動作です。

    • EMPTY STRING ON NULL— 入力のSQL NULL値が、出力のJSONオブジェクトまたは配列に含める空のJSON文字列""に変換されます。
  • RETURNING句—関数の戻り値に使用されるSQLデータ型です。戻り型は、JSONデータをサポートする任意のSQL型にすることができます(JSONVARCHAR2CLOBまたはBLOB)。デフォルトの戻り型(RETURNING句なし)はVARCHAR2(4000)です。

  • STRICTキーワード—指定すると、戻されるJSONデータが整形式になっているかチェックされます。STRICTを指定して戻されたデータが整形式でない場合には、エラーが発生します。

    ノート:

    通常、JSONデータ型のデータの生成時にSTRICTを指定する必要はなく、これを行うと若干のパフォーマンス・ペナルティが生じます。

    入力データおよび返されるデータの両方がJSON型の場合、STRICTを指定しないと、その入力は返されるデータにそのまま使用されます。厳密な整形式としてチェックされません。

    (1)入力データもJSON型であり、(2)それが完全に厳密ではない可能性がある場合、JSON型のデータを返すときにSTRICTを使用できます。たとえば、クライアント・アプリケーションで入力データが作成され、各JSON文字列が有効なUTF-8のバイト・シーケンスで表されていることが保証されない場合などです。

  • WITH UNIQUE KEYSキーワード(テキストJSONデータの生成時) — 存在する場合は、返されたJSONオブジェクトがチェックされて、重複するフィールド名がないことが確認されます。重複がある場合は、エラーが発生します。これらのキーワードは、json_objectおよびjson_objectaggの場合のみ使用できます。

    テキストJSONデータの生成時に、WITH UNIQUE KEYSが存在しない場合(またはWITHOUT UNIQUE KEYSが存在する場合)、フィールドが一意かどうかのチェックは実行されません。その場合は、重複するものを含め、すべてのフィールドが使用されます。

    WITH[OUT] UNIQUE KEYSは、JSON型のデータを生成する場合には効果がありません。戻り型がJSONである場合は、重複キーがあると必ずエラーが発生します。

JSONデータ型コンストラクタ

データ型がJSONのデータを生成する場合、json_objectおよびjson_arrayを使用するかわりに、特別な構文を持つコンストラクタJSONを使用できます。(コンストラクタJSONおよびJSON型を使用できるのは、データベース初期化パラメータcompatibleが少なくとも20の場合のみです。そうでない場合は、エラーが発生します。)

動作の違いは、コンストラクタを使用したときの戻りデータ型は、常にJSONであるということのみです(コンストラクタにはRETURNING句はありません)。

json_objectまたはjson_arrayの代替構文として使用する場合は、オブジェクトと配列の生成時に、通常のカッコ(())ではなく、中カッコ({})と大カッコ([])をそれぞれ使用して、コンストラクタJSONを直接実行します。

  • JSON { … }JSON(json_object( … ))と同じ効果があり、後者はjson_object( … RETURNING JSON)と同じ効果があります。

  • JSON [ … ]JSON(json_array( … ))と同じ効果があり、後者はjson_array( … RETURNING JSON)と同じ効果があります。

json_objectおよびjson_arrayRETURNING JSONとともに使用される場合のこれらのファンクションの動作と構文のすべての選択肢は、特別な構文を持つコンストラクタJSONを使用する場合にも利用できます。例25-2例25-3例25-4例25-5例25-6例25-8および例25-9を参照してください

JSON {…}およびJSON […]は、json_objectおよびjson_arrayのみの代替構文であり、集計生成関数json_objectaggおよびjson_arrayaggには使用できません。ただし、SQL問合せ式は引数としてjson_arrayに渡すことができるため、JSON […]の(単一)引数としても使用できます。たとえば、この2つの問合せは等価です。

SELECT json_arrayagg(department_name)FROM departments;
SELECT json_array(SELECT department_name FROM departments) FROM DUAL;

さらに、json_objectaggまたはjson_arrayaggへの明示的な呼出しの結果に対して、(特別な構文なしで)コンストラクタJSONを使用することもできます。たとえば、この2つの問合せは等価です。

SELECT JSON(json_objectagg(department_name VALUE department_id))
  FROM departments;

SELECT json_objectagg(department_name VALUE department_id
                      RETURNING JSON)
  FROM departments;

関連項目:



脚注の凡例

脚注1: JSONデータでのSQL/JSON生成関数の動作は、XMLデータのSQL/XML生成関数の動作と似ています。