23 SQL/JSONファンクションを使用したJSONデータの生成
SQL/JSONファンクションのjson_object
、json_array
、json_objectagg
およびjson_arrayagg
について説明します。
- SQL/JSONの生成関数の概要
SQL/JSONファンクションjson_object
、json_array
、json_objectagg
およびjson_arrayagg
を使用して、データベース内の非JSONデータからJSONデータを構成できます。JSONデータは、SQL値として戻されます。 - SQL/JSON生成関数の入力値の処理
SQL/JSON生成関数は入力としてSQLの値を受け取り、返されるSQL値内のJSON値としてこれらをレンダリングします。入力値をJSONとして表示する方法は、SQLデータ型によって異なります。 - SQL/JSONファンクションJSON_OBJECT
SQL/JSONファンクションjson_object
は、引数のSQL式を評価した結果からJSONオブジェクトを構成します。 - SQL/JSONファンクションJSON_ARRAY
SQL/JSONファンクションjson_array
は、引数のSQL式を評価した結果からJSON配列を構成します。 - SQL/JSONファンクションJSON_OBJECTAGG
SQL/JSONファンクションjson_objectagg
は、グループ化されたSQL問合せの複数行の情報をオブジェクト・メンバーとして集計して、JSONオブジェクトを構成します。 - SQL/JSONファンクションJSON_ARRAYAGG
SQL/JSONファンクションjson_arrayagg
は、グループ化されたSQL問合せの複数行の情報を配列要素として集計して、JSON配列を構成します。配列要素の順序は、デフォルトでは、問合せ結果の順序に反映されますが、ORDER BY
句を使用すると、配列要素の順序を指定できます。
親トピック: JSONデータの生成
23.1 SQL/JSONの生成関数の概要
SQL/JSONファンクションjson_object
、json_array
、json_objectagg
およびjson_arrayagg
を使用して、データベース内の非JSONデータからJSONデータを構成できます。JSONデータは、SQL値として戻されます。
これらの生成関数を使用すると、SQL問合せからJSONデータを直接簡単に構成できるようになります。非JSONデータをJSONオブジェクトおよびJSON配列として表すことが可能になります。これらの関数のコールをネストすることで、複雑で構造的なJSON文書を生成できます。ネストされた副問合せは、1対多関係を表すJSONコレクションを生成できます。Foot 1
非JSONデータからJSONデータを構成するための最適な方法
SQL/JSON生成関数の使用のかわりとなる方法は、エラーが発生しやすかったり、非効率的であることが一般的です。
-
文字列の連結を使用したJSON文書の生成では、エラーが発生しやすくなります。特に、二重引用符(
"
)などの特殊文字をいつ、どのようにエスケープするかという点について、順守する必要がある複雑なルールが多数あります。これらのルールは、見逃されたり誤って解釈されることが多く、その結果、正しくないJSONデータが生成される可能性が生じます。 -
非JSONの結果セットをデータベースから読み取り、クライアント側のアプリケーション・コードを使用してJSONデータを生成する方法は、特にネットワーク・オーバーヘッドが原因で非常に効率が悪くなることが一般的です。1対多関係をJSONデータとして表す場合は、必要な非JSONデータをすべて収集するために、複数の
SELECT
操作が必要になることが多くなります。生成する文書で複数のレベルの1対多関係が示される場合は、この方法では必要なコストが増えることが考えられます。
SQL/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
値として戻されます。オプションのRETURNING
句を使用して、VARCHAR2
サイズを指定するか、かわりにCLOB
またはBLOB
の戻り値を指定できます。BLOB
が戻り型の場合、文字セットはAL32UTF8です。
SQL/JSON生成関数の入力値の処理
SQL/JSON生成関数は入力としてSQLの値を受け取り、戻されるSQL値内のJSON値としてこれらをレンダリングします。入力値をJSONとして表示する方法は、SQLデータ型によって異なります。
SQL/JSON生成関数のオプションの動作
オプションとして、SQL NULL
を処理する句、RETURNING
句およびキーワードSTRICT
を指定できます。
-
NULL
を処理する句—入力評価の結果のSQLNULL
値をどのように扱うかを決定します。-
NULL ON NULL
—入力のSQLNULL
値が、出力のJSONnull
に変換されます。これは、json_object
とjson_objectagg
のデフォルト動作です。 -
ABSENT ON NULL
—入力のSQLNULL
値の結果、対応する出力がない状態になります。これは、json_array
とjson_arrayagg
のデフォルト動作です。
-
-
RETURNING
句—関数の戻り値に使用されるSQLデータ型です。デフォルトはVARCHAR2(4000)
です。 -
STRICT
キーワード—指定すると、戻されるJSONデータが整形式になっているかチェックされます。STRICT
を指定して戻されたデータが整形式でない場合には、エラーが発生します。
関連項目:
-
SQL/JSONファンクション
json_array
の詳細は、Oracle Database SQL言語リファレンスを参照してください。 -
SQL/JSONファンクション
json_arrayagg
の詳細は、Oracle Database SQL言語リファレンスを参照してください。 -
SQL/JSONファンクション
json_object
の詳細は、Oracle Database SQL言語リファレンスを参照してください。 -
SQL/JSONファンクション
json_objectagg
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
23.2 SQL/JSON生成関数の入力値の処理
SQL/JSON生成関数は入力としてSQLの値を受け取り、戻されるSQL値内のJSON値としてこれらをレンダリングします。入力値をJSONとして表示する方法は、SQLデータ型によって異なります。
デフォルトでは、SQL NUMBER
値はJSONの数値として出力に表示され、SQL VARCHAR2
値はJSON文字列として表示されます。たとえば、デフォルトではVARCHAR2
値'{}'
はJSON文字列"{}"
として表示されます。
実際に入力値がすでにJSONデータを表していることを認識しているか想定していて、値がそのまま維持されるように、これを生成関数に渡す必要がある場合があります。たとえば、入力が'{}'
の場合、JSON文字列の"{}"
ではなく、空のJSONオブジェクトの{}
として、解釈(表示)させる必要がある場合があります。
入力式の後にキーワードFORMAT JSON
を追加してこれを実行すると、そこから生成される値がすでにJSONデータを表しているとみなされることを宣言できます。同様に、キーワードAS JSON
とともにSQLファンクションtreat
を生成関数の入力値に適用できます。結果は、FORMAT JSON
を使用した場合と同じです。
多くの場合、実際に入力値がJSONデータであることは自動的に認識できますが、その場合、入力はその後に明示的なFORMAT JSON
宣言が続くかのように扱われます。これは、たとえば、値の式がSQL/JSON生成関数またはファンクションjson_query
を呼び出した場合に当てはまります。
FORMAT JSON
を特定の入力値に指定しない場合で、Oracleでも値がJSONデータであることを識別できない場合には、この値は通常の(非JSONの)SQLデータであるとみなされます。この場合は、次のようにシリアライズされます(その他のSQL値ではエラーが発生します)。
-
ユーザー定義のSQLオブジェクト型のインスタンスは、フィールド名がオブジェクト属性名から取得され、フィールド値が(JSON生成が再帰的に適用される)オブジェクト属性値から取得されるJSONオブジェクトとしてレンダリングされます。
-
SQLコレクション型のインスタンスは、(JSON生成が再帰的に適用される)コレクション要素の値から要素の値が取得されるJSON配列としてレンダリングされます。
-
VARCHAR2
、CLOB
またはNVARCHAR
値は、二重引用符("
)で囲まれ、JSON標準に準拠するように、必要に応じて文字がエスケープされます。 -
数値(
NUMBER
、BINARY_DOUBLE
またはBINARY_FLOAT
)は、JSONの数値として表示されます。(引用符では囲まれません。)正の無限大および負の無限大の数値、および数値演算の未定義の結果である値(非数値、つまり
NaN
)は、JSON数値として表すことができません。これらはかわりにJSON文字列としてレンダリングされます(それぞれ"Inf"
、"-Inf"
および"Nan"
)。 -
RAW
またはBLOB
値は、16進のJSON文字列(二重引用符"
を使用)として表示されます。 -
時間に関連した値(
DATE
、TIMESTAMP
、TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH LOCAL TIME ZONE
、INTERVAL YEAR TO MONTH
またはINTERVAL DAY TO SECOND
)は、サポートされているISO 8601形式で表示され、その結果は二重引用符("
)で囲まれます。 -
BOOLEAN
PL/SQL値はJSONのtrue
またはfalse
として表示されます。(引用符では囲まれません。) -
NULL
値は、NULL
データ型に関係なく、JSONのnull
として表示されます。(引用符では囲まれません。)
ノート:
データ型CLOB
およびBLOB
の場合、空のインスタンスはNULL
と区別され、空のJSON文字列(""
)として表示されます。ただし、データ型VARCHAR2
、NVARCHAR2
およびRAW
の場合、Oracle SQLでは空の値(長さがゼロ)をNULL
として扱うため、このような値をJSON文字列として表示されると想定しないでください。
入力引数の形式は、関数から返されるデータの形式に影響する可能性があります。特に、入力がJSONの形式であると宣言されるか、自動的に判断された場合は、戻り値の計算時にJSONデータとして扱われます。例23-1に、これを示します。ここでは、FORMAT JSON
を明示的に使用して、SQL文字列"true"
をJSONのブール値true
に解釈しています。
例23-1 入力値のJSONとしての宣言
この例では、JSONのブール値true
およびfalse
が使用されるようにするために、FORMAT JSON
をSQL文字列値'true'
および'false'
に対して指定します。FORMAT JSON
を指定しないと、フィールドhasCommission
の値はJSON文字列値"true"
および"false"
となり、JSONブール値true
およびfalse
にはなりません。
SELECT json_object('name' VALUE first_name || ' ' || last_name,
'hasCommission' VALUE
CASE WHEN commission_pct IS NULL THEN 'false' ELSE 'true'
END FORMAT JSON)
FROM employees WHERE first_name LIKE 'W%';
JSON_OBJECT('NAME'ISFIRST_NAME||''||LAST_NAME,'
-----------------------------------------------
{"name":"William Gietz","hasCommission":false}
{"name":"William Smith","hasCommission":true}
{"name":"Winston Taylor","hasCommission":false}
23.3 SQL/JSONファンクションJSON_OBJECT
SQL/JSONファンクションjson_object
は、引数のSQL式を評価した結果からJSONオブジェクトを構成します。
任意の数の引数を指定でき、各引数は次のいずれかです。
-
明示的なフィールド名/値ペア。例:
answer : 42
。名前/値ペア引数は、生成されたJSONオブジェクトのオブジェクト・メンバーを指定します(値式がSQL
NULL
に評価される場合、およびABSENT ON NULL
句が適用される場合を除く)。名前と値はSQL式です。名前式は、SQL文字列に評価される必要があります。値式は、JSON値としてレンダリングできるSQL値に評価される必要があります。名前式と値式は、キーワードVALUE
またはコロン(:
)で区切られます。ノート:
一部のクライアント・ドライバは、問合せをデータベースに送信する前に、問合せテキストのスキャンとバインド変数の特定を試みる場合があります。その場合、バインド変数を導入するときに、
json_object
内の名前/値セパレータであるコロンが誤解釈されることがあります。この問題を回避するために、キーワードVALUE
をセパレータとして使用('Name' VALUE Diderot
)するか、単にペアの値部分をカッコで囲みます('Name':(Diderot)
)。 -
リレーショナル列名。その前に表名または別名、あるいはビュー名の後にドット(
.
)が続く場合があります。例:t1.address
。この場合、指定されたデータ行について、列名引数で指定されたJSONオブジェクト・メンバーにフィールド名としての列名とフィールド値としての列値が含まれます。
引用符で囲まれているかどうかに関係なく、指定する列名は大/小文字を区別して解釈されます。たとえば、
Email
を列名引数として使用する場合、EMAIL
列のデータは、フィールド名Email
(EMAIL
ではない)を持つオブジェクト・メンバーの生成に使用されます。 -
表名または別名、あるいはビュー名の後にドットとアスタリスクのワイルドカード(
*
)。例:t1.*
。(名前や別名には、myschema.t1.*
のように、データベース・スキーマ名の接頭辞を付けることができます。)この場合、表またはビューの列はすべて入力として使用されます。それぞれが明示的に指定されたかのように処理されます。特に、列名は大/小文字を区別して解釈されます。
あるいは、json_object
では、次のいずれかである単一の引数を受け入れます。
-
ユーザー定義のSQLオブジェクト型のインスタンス。例:
json_object(my_sql_object_42)
。この場合、結果のJSONオブジェクト・フィールド名はSQLオブジェクト属性名から付けられ、その値は(JSON生成が再帰的に適用される)SQLオブジェクト属性値から取得されます。
-
アスタリスク・ワイルドカード(
*
)。例:json_object(*)
。ワイルドカードは、表またはビューのすべての列を明示的に指定してオブジェクト・メンバーを生成するためのショートカットとして機能します。結果のJSONオブジェクト・フィールド名は、大文字の列名です。ワイルドカードは、
FROM
リストからわかる表、ビューまたは表の別名とともに使用できます。列は任意のSQLデータ型にできます。この場合(
json_object(*)
)と前述の場合(アスタリスクの前に、明示的な表名またはビュー名(または表の別名)に続いてドットがある:json_object(t.*)
)の違いに注意してください。json_object(*)
の場合、列名は大/小文字を区別して解釈されません。
アスタリスク・ワイルドカードをjson_object
とともに使用する方法を説明するもう1つの方法は、SQL SELECT
一覧でワイルドカードに許可されているものに従っているということです。
SQL/JSON条件is json
と同様に、キーワードSTRICT
およびWITH UNIQUE KEYS
はファンクションjson_object
およびjson_objectagg
とともに使用できます。それぞれの動作はis json
と同じです。
例23-2 JSON_OBJECTでの名前/値ペアの使用
この例では、表hr.employees
(標準のデータベース・スキーマHR
から)の従業員のうち、給与が15000を超える従業員それぞれのJSONオブジェクトが構成されます。
明示的な名前/値のペアを渡してJSONオブジェクトのメンバーを指定します。このオブジェクトには、フィールドcontactInfo
の値として、フィールドmail
とphone
のオブジェクトが含められています。
SELECT json_object('id' : employee_id,
'name' : first_name || ' ' || last_name,
'contactInfo' : json_object('mail' : email,
'phone' : phone_number),
'hireDate' : hire_date,
'pay' : salary)
FROM hr.employees
WHERE salary > 15000;
-- The query returns rows such as this (pretty-printed here for clarity):
{"id" : 101,
"name" : "Neena Kochhar",
"contactInfo" : {"mail" : "NKOCHHAR",
"phone" : "515.123.4568"},
"hireDate" : "21-SEP-05",
"pay" : 17000}
ノート:
ファンクションjson_object
は常にJSONデータを返すため、入力フィールドcontactInfo
の値に対してFORMAT JSON
を指定する必要はありません。ただし、そのフィールドの値が'{"mail":' || email ', "phone":' || phone_number || '}'
のように指定されていた場合、その後にFORMAT JSON
を続けてその文字列値をJSONデータとして解釈する必要があります。
"contactInfo" : '{"mail":' || email ', "phone":' || phone_number || '}'
FORMAT JSON,
例23-3 JSON_OBJECTでの列名の使用
この例では、employee_id
が101
である従業員のJSONオブジェクトを構成します。生成されるフィールドには列の名前が付けられ、大/小文字が区別されます。
SELECT json_object(last_name,
'contactInfo' : json_object(email, phone_number),
hire_date,
salary)
FROM hr.employees
WHERE employee_id = 101;
-- The query returns rows such as this (pretty-printed here for clarity):
{"last_name" : "Kochhar",
"contactInfo" : {"email" : "NKOCHHAR",
"phone_number" : "515.123.4568"},
"hire-date" : "21-SEP-05",
"salary" : 17000}
例23-4 JSON_OBJECTでのワイルドカード(*)の使用
この例では、給与が15000を超える従業員ごとにJSONオブジェクトを構成します。従業員表の各列は、そのフィールド名が(大文字)列名である1つのオブジェクト・メンバーの構成に使用されます。SQL NULL
値によってJSONフィールド値がnull
になることに注意してください。
SELECT json_object(*)
FROM hr.employees
WHERE salary > 15000;
-- The query returns rows such as this (pretty-printed here for clarity):
JSON_OBJECT(*)
--------------
{"EMPLOYEE_ID":100,
"FIRST_NAME":"Steven",
"LAST_NAME":"King",
"EMAIL":"SKING",
"PHONE_NUMBER":"515.123.4567",
"HIRE_DATE":"2003-06-17T00:00:00",
"JOB_ID":"AD_PRES",
"SALARY":24000,
"COMMISSION_PCT":null,
"MANAGER_ID":null,
"DEPARTMENT_ID":90}
{"EMPLOYEE_ID":101,
"FIRST_NAME":"Neena",
"LAST_NAME":"Kochhar",
"EMAIL":"NKOCHHAR",
"PHONE_NUMBER":"515.123.4568",
"HIRE_DATE":"2005-09-21T00:00:00",
"JOB_ID":"AD_VP",
"SALARY":17000,
"COMMISSION_PCT":null,
"MANAGER_ID":100,
"DEPARTMENT_ID":90}
{"EMPLOYEE_ID":102,
"FIRST_NAME":"Lex",
"LAST_NAME":"De Haan",
"EMAIL":"LDEHAAN",
"PHONE_NUMBER":"515.123.4569",
"HIRE_DATE":"2001-01-13T00:00:00",
"JOB_ID":"AD_VP",
"SALARY":17000,
"COMMISSION_PCT":null,
"MANAGER_ID":100,
"DEPARTMENT_ID":90}
例23-5 ABSENT ON NULLを指定したJSON_OBJECTの使用
この例では、標準のデータベース・スキーマHR
の表hr.locations
に対する問合せを実行して、フィールドcity
とprovince
が含まれるJSONオブジェクトを作成します。
json_object
に対するNULL
処理のデフォルト動作は、NULL ON NULL
です。
JSON値null
が含まれるフィールドが作成されないようにするために、この例ではABSENT ON NULL
を使用します。列city
の値が'Singapore'
のときに列state_province
がSQL値NULL
になるということは、その場所に対してprovince
フィールドが作成されていないことを意味します。
SELECT JSON_OBJECT('city' VALUE city,
'province' : state_province ABSENT ON NULL)
FROM hr.locations
WHERE city LIKE 'S%';
JSON_OBJECT('CITY'ISCITY,'PROVINCE'ISSTATE_PROVINCEABSENTONNULL)
----------------------------------------------------------------
{"city":"Southlake","province":"Texas"}
{"city":"South San Francisco","province":"California"}
{"city":"South Brunswick","province":"New Jersey"}
{"city":"Seattle","province":"Washington"}
{"city":"Sydney","province":"New South Wales"}
{"city":"Singapore"}
{"city":"Stretford","province":"Manchester"}
{"city":"Sao Paulo","province":"Sao Paulo"}
例23-6 JSON_OBJECTでのユーザー定義のオブジェクト型インスタンスの使用
この例では、オブジェクト型がshipping_t
の列shipping
を使用して表po_ship
を作成します。(SQL/JSONファンクションjson_value
を使用してJSONデータからshipping_t
インスタンスを構成します。例18-3を参照。)
次に、json_object
を使用して、列po_ship.shipping
のSQLオブジェクト型インスタンスからJSONオブジェクトを生成します。
(ここでは、わかりやすいように、問合せの出力をフォーマット出力しています。)
CREATE TABLE po_ship
AS SELECT json_value(po_document, '$.ShippingInstructions'
RETURNING shipping_t)
shipping
FROM j_purchaseorder;
DESCRIBE po_ship;
Name Null? Type
--------- ------- ----------
SHIPPING SHIPPING_T
SELECT json_object(shipping) from po_ship;
JSON_OBJECT(SHIPPING)
---------------------
{"NAME":"Alexis Bull",
"ADDRESS":{"STREET":"200 Sporting Green",
"CITY":"South San Francisco"}}
{"NAME":"Sarah Bell",
"ADDRESS":{"STREET":"200 Sporting Green",
"CITY":"South San Francisco"}}
関連項目:
-
select_list
構文の詳細は、Oracle Database SQL言語リファレンスを参照してください -
SQL/JSONファンクション
json_object
の詳細は、Oracle Database SQL言語リファレンスを参照してください。 -
SQL識別子の構文は、Oracle Database SQL言語リファレンスを参照してください。
23.4 SQL/JSONファンクションJSON_ARRAY
SQL/JSONファンクションjson_array
は、引数のSQL式を評価した結果からJSON配列を構成します。
最も単純なケースでは、json_array
に指定する評価済引数は、JSON配列要素としてJSON値に変換されるSQL値です。結果の配列には、指定する引数ごとに要素が含められます(引数式がSQL NULL
に評価される場合と、ABSENT ON NULL
句が適用される場合を除く)。配列要素の順序は、引数の順序と同じです。
json_array
の引数として使用できるSQL値には、スカラー、コレクション・インスタンス、ユーザー定義のオブジェクト型インスタンスなど、いくつかの種類があります。
例23-7 JSON_ARRAYを使用したJSON配列の構成
この例では、データベース表hr.jobs
(標準のデータベース・スキーマHR
から)に含まれる各従業員の仕事のJSONオブジェクトが構成されます。オブジェクトのフィールドは、役職と給与の範囲です。給与の範囲(フィールドsalaryRange
)は、仕事に対する最小給与と最大給与の2つの数値の配列です。これらの値は、SQL列min_salary
およびmax_salary
から取得されます。
SELECT json_object('title' VALUE job_title,
'salaryRange' VALUE json_array(min_salary, max_salary))
FROM jobs;
JSON_OBJECT('TITLE'ISJOB_TITLE,'SALARYRANGE'ISJSON_ARRAY(MIN_SALARY,MAX_SALARY))
--------------------------------------------------------------------------------
{"title":"President","salaryRange":[20080,40000]}
{"title":"Administration Vice President","salaryRange":[15000,30000]}
{"title":"Administration Assistant","salaryRange":[3000,6000]}
{"title":"Finance Manager","salaryRange":[8200,16000]}
{"title":"Accountant","salaryRange":[4200,9000]}
{"title":"Accounting Manager","salaryRange":[8200,16000]}
{"title":"Public Accountant","salaryRange":[4200,9000]}
{"title":"Sales Manager","salaryRange":[10000,20080]}
{"title":"Sales Representative","salaryRange":[6000,12008]}
{"title":"Purchasing Manager","salaryRange":[8000,15000]}
{"title":"Purchasing Clerk","salaryRange":[2500,5500]}
{"title":"Stock Manager","salaryRange":[5500,8500]}
{"title":"Stock Clerk","salaryRange":[2008,5000]}
{"title":"Shipping Clerk","salaryRange":[2500,5500]}
{"title":"Programmer","salaryRange":[4000,10000]}
{"title":"Marketing Manager","salaryRange":[9000,15000]}
{"title":"Marketing Representative","salaryRange":[4000,9000]}
{"title":"Human Resources Representative","salaryRange":[4000,9000]}
{"title":"Public Relations Representative","salaryRange":[4500,10500]}
関連項目:
SQL/JSONファンクションjson_array
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
23.5 SQL/JSONファンクションJSON_OBJECTAGG
SQL/JSONファンクションjson_objectagg
は、グループ化されたSQL問合せの複数行の情報をオブジェクト・メンバーとして集計して、JSONオブジェクトを構成します。
結果のオブジェクトに含まれるメンバーの数が引数の数を直接反映するSQL/JSONファンクションjson_object
の場合とは異なり、json_objectagg
では、結果のオブジェクトのサイズは現在の問合せ対象データを反映します。このように、問合せ対象のデータによって結果のサイズが変わる可能性があります。
例23-8 JSON_OBJECTAGGを使用したJSONオブジェクトの構成
この例では、表hr.departments
(標準のデータベース・スキーマHR
)から単一のJSONオブジェクトを構成します。その際、列department_name
から取得したフィールド名と列department_id
から取得したフィールド値が使用されます。
SELECT json_objectagg(department_name VALUE department_id) FROM departments;
-- The returned object is pretty-printed here for clarity.
-- The order of the object members is arbitrary.
JSON_OBJECTAGG(DEPARTMENT_NAMEISDEPARTMENT_ID)
----------------------------------------------
{"Administration": 10,
"Marketing": 20,
"Purchasing": 30,
"Human Resources": 40,
"Shipping": 50,
"IT": 60,
"Public Relations": 70,
"Sales": 80,
"Executive": 90,
"Finance": 100,
"Accounting": 110,
"Treasury": 120,
"Corporate Tax": 130,
"Control And Credit": 140,
"Shareholder Services": 150,
"Benefits": 160,
"Manufacturing": 170,
"Construction": 180,
"Contracting": 190,
"Operations": 200,
"IT Support": 210,
"NOC": 220,
"IT Helpdesk": 230,
"Government Sales": 240,
"Retail Sales": 250,
"Recruiting": 260,
"Payroll": 270}
関連項目
関連項目:
SQL/JSONファンクションjson_objectagg
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
23.6 SQL/JSONファンクションJSON_ARRAYAGG
SQL/JSONファンクションjson_arrayagg
は、グループ化されたSQL問合せの複数行の情報を配列要素として集計して、JSON配列を構成します。配列要素の順序は、デフォルトでは、問合せ結果の順序に反映されますが、ORDER BY
句を使用すると、配列要素の順序を指定できます。
結果の配列に含まれる要素の数が引数の数を直接反映するSQL/JSONファンクションjson_array
の場合とは異なり、json_arrayagg
では、結果の配列のサイズは現在の問合せ対象データを反映します。このように、問合せ対象のデータによって結果のサイズが変わる可能性があります。
例23-9 JSON_ARRAYAGGを使用したJSON配列の構成
この例では、表hr.employees
(標準のデータベース・スキーマHR
から)の従業員のうち、6名以上の従業員を管理するマネージャである従業員それぞれのJSONオブジェクトが構成されます。オブジェクトには、マネージャID番号、マネージャ名、そのマネージャに報告する従業員の数、それらの従業員のID番号用のフィールドがあります。
配列内に含まれる従業員のID番号の順序は、json_arrayagg
のORDER BY
句で決定されます。ORDER BY
のデフォルトの方向はASC
(昇順)です。配列要素(数値)は、数値順の昇順に並べられます。
SELECT json_object('id' VALUE mgr.employee_id,
'manager' VALUE (mgr.first_name || ' '|| mgr.last_name),
'numReports' VALUE count(rpt.employee_id),
'reports' VALUE json_arrayagg(rpt.employee_id
ORDER BY rpt.employee_id))
FROM employees mgr, employees rpt
WHERE mgr.employee_id = rpt.manager_id
GROUP BY mgr.employee_id, mgr.last_name, mgr.first_name
HAVING count(rpt.employee_id) > 6;
-- The returned object is pretty-printed here for clarity.
JSON_OBJECT('ID'ISMGR.EMPLOYEE_ID,'MANAGER'VALUE(MGR.FIRST_NAME||''||MGR.LAST_NAME)
-----------------------------------------------------------------------------------
{"id": 100,
"manager": "Steven King",
"numReports": 14,
"reports": [101,102,114,120,121,122,123,124,145,146,147,148,149,201]}
{"id": 120,
"manager": "Matthew Weiss",
"numReports": 8,
"reports": [125,126,127,128,180,181,182,183]}
{"id": 121,
"manager": "Adam Fripp",
"numReports": 8,
"reports": [129,130,131,132,184,185,186,187]}
{"id": 122,
"manager": "Payam Kaufling",
"numReports": 8,
"reports": [133,134,135,136,188,189,190,191]}
{"id": 123,
"manager": "Shanta Vollman",
"numReports": 8,
"reports": [137,138,139,140,192,193,194,195]}
{"id": 124,
"manager": "Kevin Mourgos",
"numReports": 8,
"reports": [141,142,143,144,196,197,198,199]}
例23-10 SQL副問合せを使用したネストされた配列を持つJSONオブジェクトの生成
この例は、2つの表: countries
とregions
の間のSQL左外部結合を示しています。表countries
には外部キーregion_id
があり、これは表regions
の主キーと結合され、region_id
という名前が付けられます。
問合せは、表regions
の各行に対してJSONオブジェクトを返します。これらのリージョンの各オブジェクトには、値が国オブジェクトの配列(そのリージョン内の国)であるcountries
フィールドがあります。
SELECT json_object(
'region' : region_name,
'countries' :
(SELECT json_arrayagg(json_object('id' : country_id,
'name' : country_name))
FROM countries c
WHERE c.region_id = r.region_id))
FROM regions r;
問合せは、次のようなオブジェクトになります。
{"region" : "Europe",
"countries" : [{"id" : "BE",
"name" : "Belgium"},
{"id" : "CH",
"name" : "Switzerland"},
{"id" : "DE",
"name" : "Germany"},
{"id" : "DK",
"name" : "Denmark"},
{"id" : "FR",
"name" : "France"},
{"id" : "IT",
"name" : "Italy"},
{"id" : "NL",
"name" : "Netherlands"},
{"id" : "UK",
"name" : "United Kingdom"}]}
関連項目
関連項目:
SQL/JSONファンクションjson_arrayagg
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
脚注の凡例
脚注1: JSONデータでのSQL/JSON生成関数の動作は、XMLデータのSQL/XML生成関数の動作と似ています。