22 SQLを使用したJSONデータの生成
SQLを使用すると、データベース内のJSON以外のデータからJSONオブジェクトおよび配列を生成できます。これを行うには、コンストラクタJSON
またはSQL/JSONファンクションjson_object
、json_array
、json_objectagg
およびjson_arrayagg
を使用します。
- JSON生成の概要
JSONデータの生成の概要について説明します(ベスト・プラクティス、SQL/JSON生成関数、単純なJSON
コンストラクタ構文、入力SQL値の処理、および生成されるデータ)。 - SQL/JSON生成関数の入力値の処理
SQL/JSON生成関数は、入力としてSQL値を受け取り、JSONオブジェクトまたは配列を返します。入力値を使用して、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データの生成
22.1 JSONにおける生成の概要
JSONデータの生成の概要について説明します(ベスト・プラクティス、SQL/JSON生成関数、単純なJSON
コンストラクタ構文、入力SQL値の処理、および生成されるデータ)。
データベースのJSON以外のデータからJSONデータを生成するための最適な方法は、SQLを使用する方法です。標準SQL/JSON関数json_object
、json_array
、json_objectagg
およびjson_arrayagg
は、このために設計されています。生成されるデータがJSON
型の場合は、JSON
データ型のコンストラクタ関数JSON
を使用することが便利な代替の方法です。
どちらの方法を使用しても、SQL問合せからJSONデータを直接簡単に作成できます。非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データを構成するジョブ向けに設計されています。
-
これらの関数では、常に整形式の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
サイズを指定するか、かわりにJSON
、CLOB
またはBLOB
の戻り値を指定できます。BLOB
が戻り型の場合、キャラクタ・セットはAL32UTF8です。
戻り型がJSON
である場合を除き、入力SQL値から生成されるJSON値はテキストのJSONにシリアライズされます。このシリアライズは、Oracle SQLファンクションjson_serialize
と同じ効果があります。
SQL/JSON生成関数の入力値の処理
SQL/JSON生成関数は入力としてSQLの値を受け取り、返されるJSONオブジェクトまたは配列内にJSON値を生成します。出力に使用されるJSON値が入力値からどのように生成されるかは、それらのSQLデータ型によって異なります。
SQL/JSON生成関数のオプションの動作
オプションとして、SQL NULL
を処理する句、RETURNING
句およびキーワードSTRICT
およびWITH UNIQUE KEYS
を指定できます。
-
NULL
を処理する句: 入力評価の結果のSQLNULL
値をどのように扱うかを決定します。-
NULL ON NULL
: 入力のSQLNULL
値が、出力のJSONnull
に変換されます。これは、json_object
とjson_objectagg
のデフォルト動作です。 -
ABSENT ON NULL
: 入力のSQLNULL
値の結果、対応する出力がない状態になります。これは、json_array
とjson_arrayagg
のデフォルト動作です。
-
-
RETURNING
句: 関数の戻り値に使用されるSQLデータ型です。戻り型は、JSONデータをサポートする任意のSQL型にすることができます(JSON
、VARCHAR2
、CLOB
またはBLOB
)。デフォルトの戻り型(RETURNING
句なし)はVARCHAR2(4000)
です。 -
STRICT
キーワード: 指定すると、戻されるJSONデータが整形式になっているかチェックされます。STRICT
を指定して戻されたデータが整形式でない場合には、エラーが発生します。注意:
通常、
JSON
データ型のデータの生成時にSTRICT
を指定する必要はなく、これを行うと若干のパフォーマンス・ペナルティが生じます。入力データおよび返されるデータの両方が
JSON
型の場合、STRICT
を指定しないと、その入力は返されるデータにそのまま使用されます。厳密な整形式としてチェックされません。(1)入力データも
JSON
型であり、(2)それが完全に厳密ではない可能性がある場合、JSON
型のデータを返すときにSTRICT
を使用できます。たとえば、クライアント・アプリケーションで入力データが作成され、各JSON文字列が有効なUTF-8のバイト・シーケンスで表されていることが保証されない場合などです。 -
WITH UNIQUE KEYS
キーワード(json_object
およびjson_objectagg
にのみ使用可能) — 存在する場合、返されるJSONオブジェクトがチェックされ、重複するフィールド名がないことが確認されます。重複がある場合は、エラーが発生します。指定しない場合(または
WITHOUT UNIQUE KEYS
が指定されている場合)、一意のフィールドのチェックは実行されません。その場合は次のようになります。-
戻りデータ型が
JSON
の場合は、重複する一連のフィールドのうちの1つのみが使用され、どのフィールドが使用されるかは定義されていません。 -
戻りデータ型が
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_array
がRETURNING JSON
とともに使用される場合のこれらのファンクションの動作と構文のすべての選択肢は、特別な構文を持つコンストラクタJSON
を使用する場合にも利用できます。たとえば、例22-2、例22-3、例22-4、例22-5および例22-6を参照してください。
JSON {…}
およびJSON […]
は、json_object
およびjson_array
のみの代替構文であり、集計生成関数json_objectagg
およびjson_arrayagg
には使用できません。ただし、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;
関連項目:
-
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言語リファレンスを参照してください。
親トピック: SQLを使用したJSONデータの生成
22.2 SQL/JSON生成関数の入力値の処理
SQL/JSON生成関数は、入力としてSQL値を受け取り、JSONオブジェクトまたは配列を返します。入力値を使用して、JSONオブジェクトのフィールド値のペアまたはJSON配列の要素を生成します。入力値を使用する方法は、SQLデータ型によって異なります。
返されるJSONオブジェクトまたは配列は、JSONデータをサポートするSQLデータ型です(JSON
、VARCHAR2
、CLOB
またはBLOB
)。デフォルトの戻り型はVARCHAR2(4000)
です。すべての場合に、戻り値には整形式のJSONデータが含まれていることをデータベースが認識します。
JSON
データ型以外の場合、入力の後にキーワードFORMAT JSON
を指定できます。このキーワードは、値がすでにJSONデータを表しているとみなされるように宣言するため(ユーザーがそれを保証します)、JSONデータとして解釈(解析)されます。たとえば、入力が'{}'
の場合に、JSON文字列"{}"
ではなく、空のJSONオブジェクト{}
を生成する場合があります。例22-1では、FORMAT JSON
を使用して、入力SQL文字列"true"
からJSONのブール値true
を生成しています。
同様に、入力の型がJSON
でない場合、SQLファンクションtreat
にキーワードAS JSON
を指定して適用できます。効果は、FORMAT JSON
を使用した場合と同じです。
入力データがJSON
型の場合は、そのまま使用されます。これには、JSON
型コンストラクタが使用される場合も含まれます。(この場合、FORMAT JSON
またはtreat
… AS JSON
を使用しないでください。使用するとエラーが発生します。)
入力がJSON
型ではなく、FORMAT JSON
またはtreat
… AS JSON
を使用しない場合でも、Oracleは結果がJSONデータであることを認識します。そのような場合、FORMAT JSON
またはtreat
… AS JSON
を使用することは必須ではなく、任意です。これは、たとえば、入力データがファンクションjson_query
またはJSON生成関数のいずれかを使用した結果である場合です。
何らかの方法で入力がJSONデータと認識されている場合、その入力は基本的にそのまま使用されて、結果が構成されます(処理は不要です)。これは入力がJSONスカラー、オブジェクトまたは配列のいずれを表すかにかかわらず適用されます。
入力がJSONデータであると認識されない場合は、次のようなJSON値が生成されます(他のSQL値の場合はエラーが発生します)。
-
ユーザー定義のSQLオブジェクト型のインスタンスの場合は、フィールド名がオブジェクト属性名から取得され、フィールド値が(JSON生成が再帰的に適用される)オブジェクト属性値から取得されるJSONオブジェクトが生成されます。
-
SQLコレクション型のインスタンスの場合は、(JSON生成が再帰的に適用される)コレクション要素の値から要素の値が取得されるJSON配列が生成されます。
-
VARCHAR2
、CLOB
またはNVARCHAR
値は、二重引用符("
)で囲まれ、JSON標準のJSON文字列に準拠するように、必要に応じて文字がエスケープされます。たとえば、SQL入力'{}'
の場合は、JSON文字列"{}"
が生成されます。 -
数値の場合は、JSON数値が生成されます。
compatible
が少なくとも20
であれば、入力がNUMBER
の場合はJSONのnumber、BINARY_DOUBLE
の場合はJSONのdouble値、およびBINARY_FLOAT
の場合はJSONのfloat値が生成されます。データベース初期化パラメータ
compatible
が20
より低い場合、数値入力型(NUMBER
、BINARY_DOUBLE
またはBINARY_FLOAT
)に関係なく、値はJSONのnumberになります。正の無限大および負の無限大の数値、および数値演算の未定義の結果である値(非数値、つまり
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形式が生成され、その結果はJSON文字列として二重引用符("
)で囲まれます。 -
BOOLEAN
PL/SQL値のTRUE
またはFALSE
の場合は、JSONのtrue
またはfalse
がそれぞれ生成されます。 -
SQLの
NULL
値の場合は、NULL
データ型に関係なく、JSONのnull
が生成されます。
注意:
CLOB
およびBLOB
データ型の入力の場合は、空のインスタンスがSQLのNULL
と区別されます。空のJSON文字列(""
)が生成されます。ただし、データ型VARCHAR2
、NVARCHAR2
およびRAW
の入力の場合、Oracle SQLでは空の値(長さがゼロ)をNULL
として扱うため、そのような値がJSON文字列に生成されると想定しないでください。
例22-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}
親トピック: SQLを使用したJSONデータの生成
22.3 SQL/JSONファンクションJSON_OBJECT
SQL/JSONファンクションjson_object
は、引数のSQL式を評価した結果からJSONオブジェクトを構成します。
任意の数の引数を指定でき、各引数は次のいずれかにできます。
-
明示的なフィールド名/値ペア。例:
answer : 42
。 -
表名または別名、あるいはビュー名の後にドットとアスタリスクのワイルドカード(
.*
)。例:t1.*
。(名前や別名には、myschema.t1.*
のように、データベース・スキーマ名の接頭辞を付けることができます。) -
リレーショナル列名。その前に表名または別名、あるいはビュー名の後にドット(
.
)が続く場合があります。例:t1.address
。
あるいは、アスタリスク・ワイルドカード(*
)またはユーザー定義のSQLオブジェクト型の単一インスタンスである単一の引数を受け入れます。
アスタリスク・ワイルドカードの使用方法を説明するもう1つの方法は、SQL SELECT
一覧でワイルドカードに許可されているものに従っているということです。
名前/値ペア引数は、生成されたJSONオブジェクトのオブジェクト・メンバーを指定します(値式がSQL NULL
に評価される場合、およびABSENT ON NULL
句が適用される場合を除く)。名前と値はSQL式です。名前式は、SQL文字列に評価される必要があります。値式は、JSON
データ型のSQL値、またはJSON値として表すことができるSQL値に評価される必要があります。名前式と値式は、キーワードVALUE
またはコロン(:
)で区切られます。
注意:
一部のクライアント・ドライバは、問合せをデータベースに送信する前に、問合せテキストのスキャンとバインド変数の特定を試みる場合があります。その場合、バインド変数を導入するときに、json_object
内の名前/値セパレータであるコロンが誤解釈されることがあります。この問題を回避するために、キーワードVALUE
をセパレータとして使用('Name' VALUE Diderot
)するか、単にペアの値部分をカッコで囲みます('Name':(Diderot)
)。
列名を引数として使用する場合は、指定されたデータ行について、列名引数で指定されたオブジェクト・メンバーにフィールド名としての列名とフィールド値としての列値が含まれます。引用符で囲まれているかどうかに関係なく、指定する列名は大/小文字を区別して解釈されます。たとえば、Email
を列名引数として使用する場合、EMAIL
列のデータは、フィールド名Email
を持つオブジェクト・メンバーの生成に使用されます。
アスタリスク(*
)ワイルドカードをショートカットとして使用し、特定の表またはビューの列をすべて明示的に指定してオブジェクト・メンバーを作成できます。結果のオブジェクト・フィールド名は、大文字の列名です。ワイルドカードは、表、ビューまたは表の別名とともに使用できます。
個々のJSONオブジェクト・メンバーの定義に使用されるSQL式を渡すかわりに、ユーザー定義のSQLオブジェクト型の単一インスタンスを渡すことができます。これにより、フィールド名がオブジェクト属性名から取得され、フィールド値が(JSON生成が再帰的に適用される)オブジェクト属性値から取得されるJSONオブジェクトが生成されます。
SQL/JSON条件is json
と同様に、キーワードSTRICT
およびWITH UNIQUE KEYS
はファンクションjson_object
およびjson_objectagg
とともに使用できます。それぞれの動作はis json
と同じです。
例22-2 JSON_OBJECTでの名前/値ペアの使用
この例では、表hr.employees
(標準のデータベース・スキーマHR
から)の従業員のうち、給与が15000を超える従業員それぞれのJSONオブジェクトが構成されます。
明示的な名前/値のペアを渡してJSONオブジェクト・メンバーを指定します。JSONオブジェクトには、フィールドcontactInfo
の値として、フィールドmail
とphone
のオブジェクトが含められています。
json_object
の戻り値はJSONデータになるため、フィールドcontactInfo
の入力形式に対してFORMAT JSON
が自動的に推定されており、明示的にFORMAT JSON
を使用するは必要ありません。
ここではRETURNING JSON
を使用することで、デフォルトの戻り型VARCHAR2(4000)
ではなく、JSONデータがJSON
データ型として返されるように指定しています。
SELECT json_object('id' : employee_id,
'name' : first_name || ' ' || last_name,
'hireDate' : hire_date,
'pay' : salary,
'contactInfo' : json_object('mail' : email,
'phone' : phone_number
FORMAT JSON)
RETURNING JSON)
FROM hr.employees
WHERE salary > 15000;
-- The query returns rows such as this (pretty-printed here for clarity):
{"id" : 101,
"name" : "Neena Kochhar",
"hireDate" : "21-SEP-05",
"pay" : 17000,
"contactInfo" : {"mail" : "NKOCHHAR",
"phone" : "515.123.4568"}}
JSONデータの戻り型はJSON
であるため、これは同じ問合せの代替の構文です。
SELECT JSON { 'id' : employee_id,
'name' : first_name || ' ' || last_name,
'hireDate' : hire_date,
'pay' : salary,
'contactInfo' : JSON { 'mail' : email,
'phone' : phone_number } }
FROM hr.employees
WHERE salary > 15000;
例22-3 JSON_OBJECTでの列名の使用
この例では、employee_id
が101
である従業員のJSONオブジェクトを構成します。生成されるフィールドには列の名前が付けられ、大/小文字が区別されます。
SELECT json_object(last_name,
hire_date,
salary,
'contactInfo' : json_object(email, phone_number)
RETURNING JSON)
FROM hr.employees
WHERE employee_id = 101;
-- The query returns rows such as this (pretty-printed here for clarity):
{"last_name" : "Neena Kochhar",
"hire-date" : "21-SEP-05",
"salary" : 17000,
"contactInfo" : {"email" : "NKOCHHAR",
"phone_number" : "515.123.4568"}}
JSONデータの戻り型はJSON
であるため、これは同じ問合せの代替の構文です。
SELECT JSON { last_name,
hire_date,
salary,
'contactInfo' : JSON { email, phone_number } }
FROM hr.employees
WHERE employee_id = 101;
例22-4 JSON_OBJECTでのワイルドカード(*)の使用
この例では、給与が15000を超える従業員ごとにJSONオブジェクトを構成します。従業員表の各列は、そのフィールド名が(大文字)列名である1つのオブジェクト・メンバーの構成に使用されます。SQL NULL
値によってJSONフィールド値がnull
になることに注意してください。
SELECT json_object(* RETURNING JSON)
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}
JSONデータの戻り型はJSON
であるため、これは同じ問合せの代替の構文です。
SELECT JSON { * }
FROM hr.employees
WHERE salary > 15000;
例22-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"}
この例にはRETURNING
句がないため、JSONデータはデフォルトでVARCHAR2(4000)
として返されます。RETURNING JSON
を使用した場合は、問合せにこの代替の構文を使用できます。
SELECT JSON {'city' VALUE city,
'province' : state_province ABSENT ON NULL}
FROM hr.locations
WHERE city LIKE 'S%';
例22-6 JSON_OBJECTでのユーザー定義のオブジェクト型インスタンスの使用
この例では、オブジェクト型がshipping_t
の列shipping
を使用して表po_ship
を作成します。(SQL/JSONファンクションjson_value
を使用してJSONデータからshipping_t
インスタンスを構成します。例17-3を参照。)
次に、json_object
を使用して、po_ship.shipping
列にあるSQLオブジェクト型インスタンスからJSONオブジェクトを生成し、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 RETURNING JSON)
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"}}
json_object
の戻り型はJSON
であるため、これは同じ問合せの代替の構文です。
SELECT JSON {shipping} FROM po_ship;
関連項目:
-
select_list
構文の詳細は、Oracle Database SQL言語リファレンスを参照してください -
SQL/JSONファンクション
json_object
および同等のJSON
コンストラクタ({…}
)の構文の詳細は、Oracle Database SQL言語リファレンス -
SQL識別子の構文は、Oracle Database SQL言語リファレンスを参照してください。
親トピック: SQLを使用したJSONデータの生成
22.4 SQL/JSONファンクションJSON_ARRAY
SQL/JSONファンクションjson_array
は、引数のSQL式を評価した結果からJSON配列を構成します。
最も単純なケースでは、json_array
に指定する評価済引数は、JSON配列要素としてJSON値が生成されるSQL値です。結果の配列には、指定する引数ごとに要素が含められます(引数式がSQL NULL
に評価される場合と、ABSENT ON NULL
句が適用される場合を除く)。配列要素の順序は、引数の順序と同じです。
json_array
の引数として使用できるSQL値には、SQLスカラー、コレクション・インスタンス、ユーザー定義のオブジェクト型インスタンスなど、いくつかの種類があります。
例22-7 JSON_ARRAYを使用したJSON配列の構成
この例では、データベース表hr.jobs
(標準のデータベース・スキーマHR
から)に含まれる各従業員の仕事のJSONオブジェクトが構成されます。オブジェクトのフィールドは、役職と給与の範囲です。給与の範囲(フィールドsalaryRange
)は、仕事に対する最小給与と最大給与の2つの数値の配列です。これらの値は、SQL列min_salary
およびmax_salary
から取得されます。
ここではRETURNING JSON
を使用することで、デフォルトの戻り型VARCHAR2(4000)
ではなく、JSONデータがJSON
データ型として返されるように指定しています。
SELECT json_object('title' VALUE job_title,
'salaryRange' VALUE json_array(min_salary, max_salary)
RETURNING JSON)
FROM jobs;
JSON_OBJECT('TITLE'ISJOB_TITLE,'SALARYRANGE'ISJSON_ARRAY(MIN_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]}
JSONデータの戻り型はJSON
であるため、これは同じ問合せの代替の構文です。
SELECT JSON { 'title' VALUE job_title,
'salaryRange' VALUE JSON [ min_salary, max_salary ] }
FROM jobs;
関連項目:
SQL/JSONファンクションjson_array
および同等のJSON
コンストラクタ([…]
)の構文の詳細は、Oracle Database SQL言語リファレンス
親トピック: SQLを使用したJSONデータの生成
22.5 SQL/JSONファンクションJSON_OBJECTAGG
SQL/JSONファンクションjson_objectagg
は、グループ化されたSQL問合せの複数行の情報をオブジェクト・メンバーとして集計して、JSONオブジェクトを構成します。
結果のオブジェクトに含まれるメンバーの数が引数の数を直接反映するSQL/JSONファンクションjson_object
の場合とは異なり、json_objectagg
では、結果のオブジェクトのサイズは現在の問合せ対象データを反映します。このように、問合せ対象のデータによって結果のサイズが変わる可能性があります。
例22-8 JSON_OBJECTAGGを使用したJSONオブジェクトの構成
この例では、表hr.departments
(標準のデータベース・スキーマHR
)から単一のJSONオブジェクトを構成します。その際、列department_name
から取得したフィールド名と列department_id
から取得したフィールド値が使用されます。
SQL/JSON条件is json
と同様に、キーワードSTRICT
およびWITH UNIQUE KEYS
はファンクションjson_object
およびjson_objectagg
とともに使用できます。それぞれの動作はis json
と同じです。
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言語リファレンスを参照してください。
親トピック: SQLを使用したJSONデータの生成
22.6 SQL/JSONファンクションJSON_ARRAYAGG
SQL/JSONファンクションjson_arrayagg
は、グループ化されたSQL問合せの複数行の情報を配列要素として集計して、JSON配列を構成します。配列要素の順序は、デフォルトでは、問合せ結果の順序に反映されますが、ORDER BY
句を使用すると、配列要素の順序を指定できます。
結果の配列に含まれる要素の数が引数の数を直接反映するSQL/JSONファンクションjson_array
の場合とは異なり、json_arrayagg
では、結果の配列のサイズは現在の問合せ対象データを反映します。このように、問合せ対象のデータによって結果のサイズが変わる可能性があります。
例22-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]}
関連項目
関連項目:
SQL/JSONファンクションjson_arrayagg
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
親トピック: SQLを使用したJSONデータの生成
脚注の凡例
脚注1: JSONデータでのSQL/JSON生成関数の動作は、XMLデータのSQL/XML生成関数の動作と似ています。