16 SQL/JSONファンクションJSON_QUERY

SQL/JSONファンクションjson_queryは、1つ以上の値をJSONデータから選択し、JSON値を表す文字列(VARCHAR2)を戻します。(関数json_valueとは異なり、戻されるデータ型をNUMBERにすることはできません。)したがって、json_queryを使用してJSON文書のフラグメントを取得できます。

json_queryの最初の引数は、スカラーのSQLデータ型のインスタンスを戻すSQL式です(つまり、オブジェクト・データ型でもコレクション・データ型でもありません)。これは、データ型VARCHAR2BLOBまたはCLOBのいずれかになります。これは、適切にキャストされた表またはビューの列の値、PL/SQL変数、バインド変数のいずれかになります。SQL式の評価の結果は、パス式を評価するためのコンテキスト項目として使用されます。

json_queryの2番目の引数はSQL/JSONパス式であり、オプションでRETURNING句、WRAPPER句、ON ERROR句およびON EMPTY句が付加されます。このパス式は、任意の数のJSON値を対象とすることができます。

RETURNING句で指定できるのはデータ型VARCHAR2のみであり、NUMBERを指定することはできません。

ラッパー句により、戻される文字列値の形式が決まります。

json_queryのエラー句ではEMPTY ON ERRORを指定でき、これは、エラーの場合は空の配列([])が戻されることを意味します(エラーは発生しない)。

例16-1は、SQL/JSONファンクションjson_queryとともに配列ラッパーを使用する例を示しています。文書ごとにVARCHAR2値が戻され、この内容は、電話のタイプの要素が不特定の順序で含まれるJSON配列を表します。例4-2の文書では、電話のタイプは"Office"および"Mobile"であり、戻される配列は["Mobile", "Office"]または["Office", "Mobile"]です。

例16-1でパス式$.ShippingInstructions.Phone.typeが使用されていたとしても、同じ結果が得られるはずであることに注意してください。SQL/JSONのパス式構文の緩和のため、[*].type.typeに相当します。

json_queryの詳細は、Oracle Database SQL言語リファレンスを参照してください。

例16-1 JSON_QUERYを使用したJSON値の選択

SELECT json_query(po_document, '$.ShippingInstructions.Phone[*].type'
                               WITH WRAPPER)
  FROM j_purchaseorder;

トピック:

16.1 JSON_TABLEとしてのJSON_QUERY

SQL/JSONファンクションjson_queryは、関数json_tableの特別な事例であるとみなすことができます。

例16-2に、この対応を示します。2つのSELECT文で得られる結果は同じになります。

この対応は、おそらくjson_queryについてより深く理解する手助けとなるのみでなく、どちらの関数を使用しても同じ結果が得られることを意味しているため、実質的に重要な意味を持ちます。

特に、json_queryを複数回使用する場合、またはこれをjson_existsまたはjson_value (これらもjson_tableを使用して表すことができます)と組み合せて使用して同じデータにアクセスする場合、json_tableを1回呼び出す方が、データが解析されるのが1回のみであるという利点があります。

このため、オプティマイザがjson_existsjson_valueおよびjson_queryの複数の呼出し(任意の組合せ)を、より少ないjson_tableの呼出しに自動的にリライトすることがよく起こります。

例16-2 JSON_TABLEを使用して表されたJSON_QUERY

SELECT json_query(column, json_path
                  RETURNING data_type array_wrapper error_hander ON ERROR)
  FROM table;

SELECT jt.column_alias
  FROM table,
       json_table(column, '$' error_handler ON ERROR
         COLUMNS ("COLUMN_ALIAS" data_type FORMAT JSON array_wrapper
                  PATH json_path)) AS "JT";