17 JSON用のSQLファンクションおよび条件で使用される句
JSONデータを使用するSQLファンクションのためのPASSING
、RETURNING
、ラッパー、エラー、空白フィールドおよび不一致の句について説明します。それぞれの句は、SQLファンクションおよび条件のjson_value
、json_query
、json_table
、json_serialize
、json_transform
、json_mergepatch
、is json
、is not json
、json_exists
およびjson_equal
のうちのいずれかまたは複数で使用されます。
- SQLファンクションおよび条件のPASSING句
Oracle SQLファンクションのjson_transform
、SQL/JSONファンクションのjson_value
およびjson_query
、SQL/JSON条件のjson_exists
では、オプションのPASSING
句を受け入れます。この句では、パス式で使用するためにSQL値をSQL/JSON変数にバインドします。 - SQL問合せファンクションで使用されるRETURNING句
SQLファンクションjson_value
、json_query
、json_serialize
およびjson_mergepatch
は、オプションでRETURNING
句を受け入れます。この句は、ファンクションから返される値のデータ型を指定します。この句についてと、デフォルト動作(RETURNING
句なし)について説明します。 - SQL/JSON問合せファンクションJSON_QUERYおよびJSON_TABLEで使用されるラッパー句
SQL/JSON問合せファンクションのjson_query
およびjson_table
は、オプションのラッパー句を受け入れます。これには、json_query
によって返される値、またはjson_table
列のデータに使用される値の形式を指定します。この句についてと、デフォルト動作(ラッパー句なし)について説明します。例を示します。 - SQLファンクションおよび条件のエラー句
JSONデータに対する一部のSQL問合せファンクションおよび条件は、オプションでエラー句を受け入れます。この句によって、ファンクションまたは条件によって発生した実行時エラーの処理方法を指定します。この句についてと、デフォルト動作(エラー句なし)についてまとめます。 - SQL/JSON問合せファンクションで使用される空白フィールド句
SQL/JSON問合せファンクションのjson_value
、json_query
およびjson_table
は、オプションでON EMPTY
句を受け入れます。これは、対象となるJSONフィールドが問合せデータ内にない場合の処理を指定します。この句についてと、デフォルト動作(ON EMPTY
句なし)について説明します。 - SQL/JSON問合せファンクションで使用されるON MISMATCH句
ON MISMATCH
句をSQL/JSONファンクションjson_value
、json_query
およびjson_table
で使用して、型照合の例外を処理できます。対象のJSON値が指定のSQL戻り値と一致しない場合に使用する処理を指定します。この句についてと、デフォルト動作(ON MISMATCH
句なし)について説明します。 - SQLファンクションおよび条件のTYPE句
Oracle SQLファンクションのjson_transform
、SQL/JSONファンクションのjson_query
、json_value
とjson_table
およびSQL/JSON条件のjson_exists
では、オプションのTYPE
句を受け入れます。この句では、JSON値がJSON言語の型に関して厳密に(つまり、関連する"only"データ型変換項目メソッドが比較対象のデータに適用されたかのように)比較されるかどうかを指定します。
親トピック: JSONデータの問合せ
17.1 SQLファンクションおよび条件のPASSING句
Oracle SQLファンクションのjson_transform
、SQL/JSONファンクションのjson_value
およびjson_query
、SQL/JSON条件のjson_exists
では、オプションのPASSING
句を受け入れます。この句では、パス式で使用するためにSQL値をSQL/JSON変数にバインドします。
キーワードPASSING
の後に、カンマで区切られた1つ以上のSQL/JSON変数バインディング(42 AS "d"
など)が続きます。
各バインディングは、(1)評価するSQL式、(2)キーワードAS
、(3)SQL/JSON変数名で構成されます。脚注1バインディング42 AS "d"
は、式の値42
をd
という名前のSQL/JSON変数にバインドします。これは、$.PONumber?(@ > $d)
などのパス式で使用できます。
PASSING
句をTYPE (STRICT)
句とともに使用すると、パス式のSQL/JSON変数と比較される各値が、関連する"only"データ型変換項目メソッドが値に適用されたかのように、JSON言語の型に関して厳密に比較されます。比較に使用される型は、SQL/JSON変数の型です。
たとえば、TYPE (STRICT)
と指定した場合、変数$d
の数値の値に対する$.PONumber?(@ > $d)
などの比較は、$.PONumber?(@.numberOnly() > $d)
であるかのように暗黙的に処理されます。そのため、これらの2つの問合せは同じ動作をします。$d
の値は数値であるため、値が数値であるPONumber
フィールドのみが考慮されます。
SELECT count(*) FROM j_purchaseorder
WHERE json_exists(po_document, '$.PONumber?(@.numberOnly() > $d)'
PASSING to_number(:1) AS "d");
SELECT count(*) FROM j_purchaseorder
WHERE json_exists(po_document, '$.PONumber?(@ > $d)'
PASSING to_number(:1) AS "d" TYPE(STRICT));
評価する式のデータ型は、JSON
、VARCHAR2
、NUMBER
、BINARY_DOUBLE
、DATE
、TIMESTAMP
またはTIMESTAMP WITH TIME ZONE
である必要があり、それ以外の場合は、エラーが発生します。
式がSQLのNULL
値に評価される場合、その結果は、次のように、そのNULL
値のSQL型に応じて異なります:
-
SQL型
JSON
のNULL
を渡すと、エラーが発生します。 -
SQL型
VARCHAR2
のNULL
を渡すと、その変数は空のJSON文字列""
にバインドされます。 -
SQL型
RAW
のNULL
を渡すと、その変数は長さゼロのJSONバイナリ値にバインドされます。 -
その他のSQL型の
NULL
を渡すと、その変数はJSONのnull
値にバインドされます。
ノート:
SQL/JSON変数名にはSQL識別子の構文がありますが、次の制限があります。
-
SQL/JSON変数名には、その定義に使用されるSQL識別子に引用符文字が含まれていても、引用符文字は含まれません。
JSONファンクションおよび条件の
PASSING
句では、キーワードAS
に続くSQL識別子は、引用符で囲まれた識別子または引用符で囲まれていない識別子(AS "d"
やAS d
など)にすることができます。これは、1つ目のケース(名前に引用符なし)ではd
という名前の、2つ目のケース(暗黙的に大文字)ではD
という名前のSQL/JSON変数を定義します。(1つ目のケースのSQL識別子はd
ではなく"d"
で、2番目のケースではd
ではなくD
です。) -
SQL/JSON変数名に使用できるのは、ASCII英数字またはASCIIアンダースコア文字(10進コード95)のみです。さらに、名前は数字ではなく文字またはアンダースコア文字で始める必要があります。たとえば、
42 AS "2d"
、42 AS "d+"
および42 AS "dã"
ではそれぞれエラーが発生し、1つ目の理由は数字で始まるため、2つ目の理由は英数字ではないASCII文字(+
)が含まれているため、3つ目の理由はASCII以外の文字(ã
)が含まれているためです。
SQL/JSON変数は、$
の後にSQL/JSON変数名が続きます。たとえば、$d
はD
という名前の変数です。
SQL/JSONパス式では、SQL識別子ではなくSQL/JSON変数が使用されます。特に、これは引用符が存在しないことを意味し、名前を直接使用します。たとえば、$.PONumber?(@ > $"d")
ではエラーが発生し、$.PONumber?(@ > $d)
が正しい構文です。
関連トピック
関連項目:
PASSING
句の詳細は、『Oracle Database SQL言語リファレンス』のJSON_EXISTS条件に関する項を参照してください
親トピック: JSON用のSQLファンクションおよび条件で使用される句
17.2 SQL問合せファンクションで使用されるRETURNING句
SQLファンクションjson_value
、json_query
、json_serialize
およびjson_mergepatch
は、オプションでRETURNING
句を受け入れます。この句は、ファンクションから返される値のデータ型を指定します。この句についてと、デフォルト動作(RETURNING
句なし)について説明します。
json_value
の場合は、RETURNING
句で次のSQLデータ型のいずれかを使用できます: VARCHAR2
、NVARCHAR2
、CHAR
、NCHAR
、BOOLEAN
、NUMBER
、BINARY_DOUBLE
、BINARY_FLOAT
、DATE
(オプションのキーワードPRESERVE TIME
またはTRUNCATE TIME
を指定)、TIMESTAMP
、TIMESTAMP WITH TIME ZONE
、INTERVAL YEAR TO MONTH
、INTERVAL DAY TO SECOND
、SDO_GEOMETRY
、RAW
脚注2、CLOB
およびNCLOB
。ユーザー定義のオブジェクト型またはコレクション型を使用することもできます。
(JSONのブール値が対象である場合の戻り型の詳細は、SQL/JSONファンクションJSON_VALUEとブール型のJSON値の使用を参照してください。)
ノート:
Oracle SQLデータ型DATE
のインスタンスには、時間コンポーネントが含まれます。JSONデータでは、ISO 8601日時値を表す文字列を使用できます。つまり、時間コンポーネントを使用できます。
デフォルトで、RETURNING DATE
を含むjson_value
は、時間コンポーネントがゼロ(ゼロ時間、分および秒)のSQL DATE
値を返します。デフォルトでは、問い合せたJSONスカラー値の時間コンポーネントは、返されたSQL DATE
インスタンスで切り捨てられます。ただし、時間の切捨てが行われる前に、ISO 8601の日時文字列で表される値にタイムゾーン・コンポーネントがある場合は、値は最初にUTCに変換され、タイムゾーン情報が考慮されます。
RETURNING DATE PRESERVE TIME
を使用すると、このデフォルトの切捨て動作をオーバーライドし、問い合せたJSONスカラー値の時間コンポーネント(存在する場合)を保持できます。(RETURNING DATE TRUNCATE TIME
の使用は、デフォルトの動作であるRETURNING DATE
とまったく同じ効果があります。)
(同じ考慮事項が、TRUNCATE TIME
に対応する項目メソッドdate()
と、PRESERVE TIME
に対応するdateWithTime()
に適用されます。)
json_query
、json_serialize
およびjson_mergepatch
の場合は、VARCHAR2
、CLOB
、BLOB
またはJSON
を使用できます。脚注3
BLOB
の結果はAL32UTF8文字セットです。json_serialize
によって返されるデータ型に関係なく、返されるデータはテキストのJSONデータを表します。
必要に応じて、VARCHAR2
の長さ(デフォルト: 4000
)、およびNUMBER
の精度とスケールを指定できます。
データ型SDO_GEOMETRY
は、Oracle Spatial and Graphデータ向けです。特に、これは、json_value
をGeoJSONデータで使用できることを意味します。このデータは、JSONで地理データをエンコーディングするための形式です。
json_query
(のみ)の場合、データベース初期化パラメータcompatible
が20
以上で、入力データがJSON
データ型のとき:
-
デフォルトの戻り型(
RETURNING
句なし)もJSON
です。それ以外の場合、デフォルトの戻り型は
VARCHAR2(4000)
です。 -
戻りデータ型に関係なく、デフォルトでは、返されるデータをスカラーJSON値にすることができます。
戻りデータ型の直後にキーワード
DISALLOW SCALARS
を含めることで、この動作をオーバーライドできます。json_query
の呼出しでは、スカラーではないJSON値のみが返されます(RFC 8259がサポートされていない場合と同じ動作になります)。
RETURNING
句は、オプションのキーワード(PRETTY
およびASCII
)も受け入れます(戻りデータ型がJSON
の場合を除く)。両方を使用する場合は、PRETTY
がASCII
の前にくる必要があります。キーワードPRETTY
はjson_value
には指定できません。
キーワードPRETTY
を使用すると、改行文字の挿入およびインデントにより、戻されたデータがわかりやすいように出力されます。デフォルトの動作では、わかりやすいようには出力されません。
キーワードASCII
を使用すると、標準のASCII Unicodeエスケープ・シーケンスを使用することにより、戻されるデータ内の非ASCII Unicode文字がすべて自動的にエスケープされます。デフォルトの動作では、非ASCII Unicode文字はエスケープされません。
ヒント:
パス式として$
のみを使用することにより、コンテキスト項目全体をわかりやすいように出力できます。
RETURNING
句でVARCHAR2
を指定した場合、値のスカラーは次のように表されます。
-
ブール値は、小文字の文字列
"true"
および"false"
で表されます。 -
null
値は、SQLNULL
で表されます。 -
JSONの数値は、正準な形式で表されます。このため、JSONの数値では、出力の文字列がテキストの入力データの表現と異なる可能性があります。正準な形式で表された場合、数値は次のようになります。
-
SQL
NUMBER
の精度と範囲の制限の対象となる場合があります。 -
SQL
NUMBER
の制限事項の対象とならない場合には、次のようになります。-
精度は40桁に制限されます。
-
オプションの指数は、9桁と1つの符号(
+
または-
)に制限されます。 -
使用できる符号(
-
、+
)、小数点(.
)および指数のインジケータ(E
)を含めて、テキスト全体が48文字に制限されます。
-
正準な形式のJSONの数値は、次のようなものです。
-
JSONの数値です。(JSONデータで数値として解析されます。)
-
先行するプラス(
+
)符号はありません。 -
必要な場合にのみ小数点(
.
)が使用されます。 -
その数値が小数(0と1の間)の場合は、小数点の前に単一のゼロ(
0
)が置かれます。 -
必要な場合にのみ指数表記法(
E
)が使用されます。これが当てはまるのは、特に、出力文字数が制限されすぎている場合です(VARCHAR2(N)
のN
が小さいことによる)。
-
OracleではSQL/JSON標準を拡張し、戻りデータ型がVARCHAR2(N)
の場合は、データ型の直後にオプションのキーワードTRUNCATE
を指定できるようにしました。TRUNCATE
が存在し、かつ戻り値がN
よりも長い場合は、値が切り捨てられ、先頭N
文字のみが戻されます。TRUNCATE
がない場合、このケースはエラーとして扱われ、エラー句またはデフォルトのエラー処理動作によって通常どおり処理されます。
ファンクションjson_value
もオプションのTYPE
句を受け入れます。TYPE (STRICT)
を使用した場合、投影された(戻された)値は、関連する"only"データ型変換項目メソッドが適用されたかのように、JSON言語の型に関して厳密に比較されます。
たとえば、この2つの問合せは等価です。値が数値であるPONumber
フィールドのみが考慮(投影)されます。
SELECT json_value(po_document, '$.PONumber.numberOnly()') FROM j_purchaseorder
RETURNING NUMBER;
SELECT json_value(po_document, '$.PONumber') FROM j_purchaseorder
RETURNING NUMBER TYPE (STRICT);
LOBを返すことができるJSONの任意のSQLファンクションの場合、デフォルトではLOBは参照によって返されます。かわりに、キーワードVALUE
を使用して戻り型(ファンクションに応じてCLOB
、BLOB
またはNCLOB
)に従うことで、値ベースのLOBを返すことができます。たとえば:
SELECT json_value(...) FROM ... RETURNING CLOB VALUE;
関連項目
関連項目:
-
SQLデータ型
DATE
およびTIMESTAMP
の詳細は、『Oracle Database SQL言語リファレンス』を参照してください -
SQLデータ型
NUMBER
の詳細は、『Oracle Database SQL言語リファレンス』を参照してください -
値ベースのLOBの詳細は、Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイドの値LOBを参照してください。
-
Oracle Spatial and Graphデータの使用の詳細は、『Oracle Spatial開発者ガイド』を参照してください
親トピック: JSON用のSQLファンクションおよび条件で使用される句
17.3 SQL/JSON問合せファンクションJSON_QUERYおよびJSON_TABLEで使用されるラッパー句
SQL/JSON問合せファンクションのjson_query
およびjson_table
は、オプションのラッパー句を受け入れます。これには、json_query
によって返される値、またはjson_table
列のデータに使用される値の形式を指定します。この句についてと、デフォルト動作(ラッパー句なし)について説明します。例を示します。
json_query
またはjson_table
列のパス式で対象とするJSONデータは、単一のJSON値(スカラー、オブジェクトまたは配列値)または複数のJSON値にすることができます。オプションのラッパー句を使用すると、対象データを配列にラップしてから返すことができます。
たとえば、対象となるデータが値"A50"
および{"a": 42}
のセットの場合、これらがラップされて配列[ "A50", {"a": 42} ]
(または[ {"a": 42}, "A50" ]
)が返されるように指定できます(要素の順序は制御できません)。または、唯一の対象値が42
の場合、これをラップして配列[42]
を返すことができます。
Oracle Database 21cより前では、RFC 4627のみがサポートされていましたが、RFC 8259はサポートされませんでした。このコンテキストでは、単一のスカラーJSON値を返すことができませんでした。エラーが発生しないように、配列にラップする必要がありました。これはデータベース初期化パラメータcompatible
が20
より低い場合に引き続き当てはまります。RFC 8259がサポートされている場合でも、結果を配列にラップする場合があります。
ラッパー句(またはラッパー句がない場合(キーワードWITHOUT WRAPPER
を使用する場合と同じ))の動作は、(1)対象となるJSONデータが単一のスカラー値であるかどうか、および(2)単一のスカラー値を返すことがSQL/JSONファンクションの特定の呼出しで許可されているかどうかに応じて異なります。
ラップを行わず、次のいずれかに該当する場合、単一のスカラー値または複数値(スカラーまたはそれ以外)が返されると、エラーが発生します。
-
データベース初期化パラメータ
compatible
が20
より低い。 -
RETURNING
句にキーワードDISALLOW SCALARS
が使用されている。
ON EMPTY
句はラッパー句より優先されます。前者のデフォルトはNULL ON EMPTY
です。これは、パス式と一致するJSON値がない場合にSQLのNULL
が返されることを意味します。かわりに空のJSON配列([]
)が返されるようにするには、EMPTY ARRAY ON EMPTY
を指定します。かわりにエラーを発生させる場合は、ERROR ON EMPTY
を指定します。
空ではない一致のためのラッパー句は次のとおりです。
-
WITH WRAPPER
- パス式と一致するすべてのJSON値を含むJSON配列を使用します。配列要素の順序は指定されません。 -
WITHOUT WRAPPER
– パス式と一致するJSON値を使用します。次のいずれかの条件に該当する場合にエラーを発生させます。
-
パス式が複数の値と一致する。
-
スカラー値を返すことができず、パス式が(オブジェクトまたは配列ではなく)単一のスカラー値と一致する。
-
-
WITH CONDITIONAL WRAPPER
- パス式と一致するすべてのJSON値を表す値を使用します。複数のJSON値と一致する場合、これは
WITH WRAPPER
と同じです。一致するJSON値が1つのみの場合:
-
スカラー値を返すことが許可される場合、または一致する単一の値がオブジェクトまたは配列の場合は、
WITHOUT WRAPPER
と同じです。 -
それ以外の場合、これは
With WRAPPER
と同じです。
-
デフォルトの動作はWITHOUT WRAPPER
です。
キーワードUNCONDITIONAL
は、コードを明確にするために使用できます。WITH WRAPPER
とWITH UNCONDITIONAL WRAPPER
は同じ内容を意味します。
キーワードARRAY
は、これを使用する方が明確になる場合はキーワードWRAPPER
の直前に追加できます。WRAPPER
とARRAY WRAPPER
は同じことを意味します。
ノート:
OMIT QUOTES
句を使用する場合は、json_query
で配列ラッパーを使用できません。使用すると、コンパイル時エラーが発生します。
表17-1は、ラッパー句の各種の使用例を示しています。配列ラッパーは太字のイタリック
で示されています。
表17-1 JSON_QUERYラッパー句の例
パス式と一致するJSON値 | WITH WRAPPER | WITHOUT WRAPPER | WITH CONDITIONAL WRAPPER |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
エラー(複数の値) |
|
なし |
|
エラー(値なし) |
|
たとえば、JSONオブジェクトを取得するためのjson_query
問合せを検討してみます。パス式が(任意の種類の)複数のJSON値と一致する場合はどうなるでしょうか。エラーを発生させずに、一致した値を取得したい場合があります。たとえば、オブジェクトである値の1つを選択し、さらに処理したい場合があります。配列ラッパーを使用すると、このような処理を行うことができます。
ラッパーを使用する理由がエラーの発生を回避することのみであり、これらのエラー事例をエラーでない事例と区別する必要がない場合、条件付きラッパーが役立ちます。アプリケーションが探しているものが単一のオブジェクトまたは配列であり、パス式によって一致したデータがそのものである場合、予期した値を単一の配列にラップする必要はありません。
一方、無条件ラッパーの場合、結果として生成される配列は常にラッパーであることが判明しています。アプリケーションはこの事実に頼ることができます。条件付きラッパーを使用する場合、アプリケーションでは、戻された配列を解析するために追加の処理を行う必要がある場合があります。たとえば、表17-1では、同じ配列([42, "a", true]
)が、この配列と一致するパス式、およびその各要素と一致するパス式という、まったく異なる事例に対して戻されています。
親トピック: JSON用のSQLファンクションおよび条件で使用される句
17.4 SQLファンクションおよび条件のエラー句
JSONデータに対する一部のSQL問合せファンクションおよび条件は、オプションでエラー句を受け入れます。この句によって、ファンクションまたは条件によって発生した実行時エラーの処理方法を指定します。この句についてと、デフォルト動作(エラー句なし)についてまとめます。
デフォルトでは、JSON用のSQLファンクションおよび条件により、実行時エラーの発生が回避されます。たとえば、JSONデータが構文的に無効な場合、json_exists
およびjson_equal
はfalseを戻し、json_value
はNULL
を戻します。
ただし、場合によってはデフォルト動作をオーバーライドするエラー句を指定することもできます。指定できるエラー処理は異なりますが、エラー処理を指定可能なJSON用の各SQLファンクションおよび条件では、少なくともエラー発生のERROR ON ERROR
動作がサポートされます。
オプションのエラー句は次の形式を使用できます。
-
ERROR ON ERROR
- エラーを発生させます(特別な処理なし)。 -
NULL ON ERROR
- エラーを発生させるかわりにNULL
を戻します。json_exists
に使用できません。 -
FALSE ON ERROR
- エラーを発生させるかわりにfalseを戻します。デフォルトである
json_exists
およびjson_equal
にのみ使用できます。 -
TRUE ON ERROR
- エラーを発生させるかわりにtrueを戻します。json_exists
およびjson_equal
にのみ使用できます。 -
EMPTY OBJECT ON ERROR
- エラーを発生させるかわりに空のオブジェクト({}
)を戻します。json_query
にのみ使用できます。 -
EMPTY ARRAY ON ERROR
- エラーを発生させるかわりに空の配列([]
)を戻します。json_query
にのみ使用できます。 -
EMPTY ON ERROR
–EMPTY ARRAY ON ERROR
と同じ。 -
DEFAULT '
literal_return_value
' ON ERROR
- エラーを発生させるかわりに指定した値を戻します。値は、問合せのコンパイル時に定数である必要があります。使用不可:
-
json_exists
、json_equal
、json_serialize
、json_scalar
、json_mergepatch
、またはjson_exists
動作が含まれたjson_table
列値句の場合 -
json_query
、またはjson_query
動作を含むjson_table
列値句 -
json_table
の低レベル・エラー処理 -
SDO_GEOMETRY
がjson_value
のRETURNING
句データ・タイプとして、またはjson_table
列データ・タイプとして指定されている場合
-
デフォルト動作は、NULL ON ERROR
ですが、条件json_exists
およびjson_equal
の場合は該当しません。
ノート:
json_table
のエラー処理には2つのレベルがありますが、これらは、パス式の2つのレベルである行と列に対応しています。存在する場合、列のエラー・ハンドラにより、行レベルのエラー処理がオーバーライドされます。両レベルのデフォルトのエラー・ハンドラはNULL ON ERROR
です。
ノート:
欠落フィールドの照合を試行したことによるエラーの場合、ON EMPTY
句はON ERROR
で指定された動作より優先されます。
ノート:
ON ERROR
句は、構文的に正しいSQL/JSONパス式がJSONデータに対して照合されたときに発生する実行時エラーに対してのみ有効です。構文的に正しくないパス式の場合、コンパイル時エラーが発生します。これは、ON ERROR
句によっては処理されません。
関連項目
関連項目:
-
JSON用のSQLファンクションのエラー句の詳細は、『Oracle Database SQL言語リファレンス』を参照してください
-
JSON用のSQL条件のエラー句の詳細は、『Oracle Database SQL言語リファレンス』を参照してください
親トピック: JSON用のSQLファンクションおよび条件で使用される句
17.5 SQL/JSON問合せファンクションで使用される空白フィールド句
SQL/JSON問合せファンクションのjson_value
、json_query
およびjson_table
は、オプションでON EMPTY
句を受け入れます。これは、対象となるJSONフィールドが問合せデータ内にない場合の処理を指定します。この句についてと、デフォルト動作(ON EMPTY
句なし)について説明します。
通常、SQL/JSONファンクションおよび条件のエラーへの対処は、エラー句(ON ERROR
)を使用して行います。しかし、データ内に見つからない特定のJSONフィールドと照合するために問合せるときのように、この通常のエラー処理とは異なる対処が必要な特別なケースがあります。照合するフィールドがないという理由だけでエラーを発生させたくない場合があります。(欠落フィールドは、通常エラーとして扱われます。)
通常は、ON ERROR
句と一緒にNULL ON EMPTY
句を使用します。このように組み合せることにより、通常のエラーはON ERROR
句に従って処理されますが、欠落フィールドの照合を試行した場合のエラーにはNULL
が戻されるだけになります。このときに、ON EMPTY
句がない場合は、ON ERROR
句で欠落フィールドのケースも処理されます。
NULL ON EMPTY
の他に、ERROR ON EMPTY
とDEFAULT
... ON EMPTY
も使用できます。これらは、同様の名前を持つON ERROR
句と類似しています。
ON EMPTY
句のみがある(ON ERROR
句がない)場合、欠落フィールドの動作はON EMPTY
句によって指定され、その他のエラーは、NULL ON ERROR
句がある場合と同じ方法で処理されます(これがON ERROR
のデフォルト)。どちらの句もない場合には、NULL ON ERROR
のみが使用されます。
ノート:
SQL/JSONファンクションjson_value
が、record型または索引付き表型のRETURNING
型が含まれているPL/SQLコードで使用されていると、NULL
が返せなくなります。これらの型は不可分的にNULL
にできないためです。
そのため、NULL ON MISMATCH
句とNULL ON EMPTY
句では、こうしたコレクション型に対してNULL
値を返せません。NULL
が返されることはなく、コンパイル時エラーが発生します。(SQLオブジェクト、VARRAYまたはネストされた表に対するRETURNING
型が含まれたPL/SQLコードの場合、それらの型の値は不可分的にNULL
にできるため、このような例外は存在しません)。
JSON_VALUEで作成された索引に対するNULL ON EMPTYの使用
NULL ON EMPTY
は、json_value
式で作成される関数索引の場合に特に便利です。この句は、索引の選択を行うかどうか、またはいつ行うかへの影響は持ちませんが、json_value
式の対象であるフィールドが欠落しているために索引付けが行われない一部のデータでインデックス付けが行われるようにすることを許可する際に有効です。
索引を移入する問合せには、通常ERROR ON ERROR
を使用することによって、問合せパス式の結果が複数の値や複雑な値になったときはエラーが発生するようにします。しかし、パス式の対象フィールドが欠落しているだけはエラーを発生させずに、そのデータをインデックス付けする場合があります。例29-4は、json_value
式で索引を作成するときのNULL ON EMPTY
の使用方法を示しています。
17.6 SQL/JSON問合せファンクションで使用されるON MISMATCH句
ON MISMATCH
句をSQL/JSONファンクションjson_value
、json_query
およびjson_table
で使用して、型照合の例外を処理できます。対象のJSON値が指定のSQL戻り値と一致しない場合に使用する処理を指定します。この句についてと、デフォルト動作(ON MISMATCH
句なし)について説明します。
ノート:
ON MISMATCH
句は、ON EMPTY
句とON ERROR
句のいずれも適用されない場合にのみ適用されます。これは一般に、対象となるJSONデータがパス式と一致するが、その対象となるデータの型が指定された戻り型と一致しない場合に適用されます。より正確には、対象となるデータが戻り型に変換できない場合にON MISMATCH
が適用されます。たとえば、対象値"cat"
(JSON文字列)は、SQL NUMBER
値に変換できません。
ON EMPTY
句は、パス式で対象とされたフィールドが問合せ対象データに存在しない場合に適用されます。
ON ERROR
句は、問合せの処理中にエラーが発生した場合に適用されます。これには、問合せ構文が無効な場合と、配列ラッパーが指定されていないjson_value
問合せまたはjson_query
問合せで複数の値を対象とする場合が含まれます。
問合せで、ファンクションjson_value
、json_query
またはjson_table
による対象となったJSONデータが反映されたSQL値が返される場合は、対象となったデータと返される値の型が一致する必要があります。そうでない場合は、エラーが発生します。
ON ERROR
ハンドラが指定されている場合は、その動作がON MISMATCH
のデフォルト動作として適用されます: これは、ON MISMATCH
句が指定されていない場合の型不一致での動作です。
型不一致の動作の指定には、次の方法で1つ以上のON MISMATCH
句を使用できます。
-
IGNORE ON MISMATCH
: デフォルトの動作(不一致を無視)を明示的に指定します。返されるオブジェクトまたはコレクションには、対象となるJSONデータに対する不一致のため、1つ以上のSQLNULL
値が含まれることがあります。この値は、問合せがユーザー定義オブジェクトまたはコレクション型のインスタンスを対象とする場合のみ使用できます。これは、
json_value
(またはjson_value
セマンティクスが含まれるjson_table
列)が使用されている場合にのみ当てはまる可能性があります。別の型のデータが対象とされると、エラーが発生します。 -
NULL ON MISMATCH
— 値としてSQLNULL
を返します。ノート:
SQL/JSONファンクション
json_value
が、record型または索引付き表型のRETURNING
型が含まれているPL/SQLコードで使用されていると、NULL
が返せなくなります。これらの型は不可分的にNULL
にできないためです。そのため、
NULL ON MISMATCH
句とNULL ON EMPTY
句では、こうしたコレクション型に対してNULL
値を返せません。NULL
が返されることはなく、コンパイル時エラーが発生します。(SQLオブジェクト、VARRAYまたはネストされた表に対するRETURNING
型が含まれたPL/SQLコードの場合、それらの型の値は不可分的にNULL
にできるため、このような例外は存在しません)。 -
ERROR ON MISMATCH
— 不一致の場合にエラーが発生します。
ファンクションjson_value
(またはjson_value
セマンティクスが含まれるjson_table
)がユーザー定義のオブジェクト型またはコレクション型のインスタンスを返す場合、ON MISMATCH
句の各型の後に、それぞれが処理する不一致の種類を示す1つ以上の句をカンマ(,
)で区切り、カッコで囲んで((
…)
)続けることができます。不一致の種類は次のとおりです。
-
MISSING DATA
—オブジェクト型またはコレクション型のデータに一致するために必要だったJSONデータが欠落していました。 -
EXTRA DATA
—1つ以上のJSONフィールドに、対応するオブジェクト型またはコレクション型のデータがありません。たとえば、JSONフィールドaddress
について、同じ名前のオブジェクト型属性がありません(デフォルトでは大文字と小文字を区別しません)。 -
TYPE ERROR
: JSONスカラー値のデータ型に、対応する戻りSQLスカラー・データ型との互換性がありません。これは、表17-2で示されている一般的な型の非互換性、またはSQLデータ型の制約が厳しすぎること(VARCHAR(2)
がJSON文字列"hello"
には短すぎるなど)が原因である可能性があります。
指定されたハンドラ(NULL ON MISMATCH
など)に対してこのような種類の不一致句(EXTRA DATA
など)が存在しない場合、そのハンドラはすべての種類の不一致に適用されます。
様々な種類のON MISMATCH
句を必要な数だけ使用できますが、2つ以上が互いに矛盾する場合は、問合せのコンパイル時エラーが発生します。
ノート:
"only"項目メソッド(名前に"only"が含まれている項目メソッド)を使用する場合は、指定したタイプの入力型の値のみ互換性があります。たとえば、項目メソッドbooleanOnly()
を使用する場合は、JSON言語型booleanの入力値のみ、リストされた変換先SQL型(BOOLEAN
、VARCHAR2
およびCLOB
)と互換性があります(変換可能)。
このコンテキストにおいては、項目メソッドidOnly()
は例外です。これは、その入力が、JSON言語型ファミリのバイナリであるだけでなく識別子として適している必要もあるためです。「JSONデータ型の値の比較とソート」も参照してください。
表17-2 互換性のあるスカラー・データ型: JSONからSQLへの変換
JSON言語型(ソース) | SQL型(宛先) | ノート |
---|---|---|
binary |
RAW |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
binary |
BLOB |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
binary |
CLOB |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
boolean |
BOOLEAN |
インスタンス値は、SQLブール値TRUE またはFALSE です。
|
boolean |
VARCHAR2 |
インスタンス値は、SQL文字列"true" または"false" です。
|
boolean |
CLOB |
インスタンス値は、SQL文字列"true" または"false" です。
|
date |
DATE 。時間コンポーネント(場合によってはゼロ)が含まれます脚注4
|
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
date |
TIMESTAMP |
時間コンポーネントにはゼロが埋め込まれます。SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
daysecondInterval |
INTERVALDAYTOSECOND |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
double |
BINARY_DOUBLE |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
double |
BINARY_FLOAT |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
double |
NUMBER |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
double |
VARCHAR2 |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
double |
CLOB |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
float |
BINARY_FLOAT |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
float |
BINARY_DOUBLE |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
float |
NUMBER |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
float |
VARCHAR2 |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
float |
CLOB |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
null |
任意のSQLデータ型。 | インスタンス値はSQL NULL です。
|
number |
NUMBER |
なし。 |
number |
BINARY_DOUBLE |
なし。 |
number |
BINARY_FLOAT |
なし。 |
number |
VARCHAR2 |
なし。 |
number |
CLOB |
なし。 |
string |
VARCHAR2 |
なし。 |
string |
CLOB |
なし。 |
string |
NUMBER |
JSON文字列は数値である必要があります。 |
string |
BINARY_DOUBLE |
JSON文字列は数値である必要があります。 |
string |
BINARY_FLOAT |
JSON文字列は数値である必要があります。 |
string |
DATE 。時間コンポーネント(場合によってはゼロ)が含まれます脚注4 |
JSON文字列は、サポートされているISO8601形式である必要があります。 |
string |
TIMESTAMP |
JSON文字列は、サポートされているISO8601形式である必要があります。 |
string |
INTERVALYEARTOMONTH |
JSON文字列は、サポートされているISO 8601継続時間形式である必要があります。 |
string |
INTERVALDAYTOSECOND |
JSON文字列は、サポートされているISO 8601継続時間形式である必要があります。 |
timestamp |
TIMESTAMP
|
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
timestamp |
DATE 。時間コンポーネント(場合によってはゼロ)が含まれます脚注4 |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
yearmonthInterval |
INTERVALYEARTOMONTH |
SQL型JSON として格納されているJSONデータに対してのみサポートされます。
|
脚注4 たとえば、ゼロの時間コンポーネントが含まれているDATE
インスタンスは時間コンポーネントの保持が指定されていないjson_value
RETURNING DATE
句によって返されます。
例17-1 ON MISMATCH句の使用
この例では、次のオブジェクト・リレーショナル・データを様々な問合せで使用します。型不一致の動作を除き、問合せは同一です。各問合せは、存在しないJSONフィールドmiddle
を対象とします。
CREATE TYPE person_T AS OBJECT (
first VARCHAR2(30),
last VARCHAR2(30),
birthyear NUMBER);
この問合せでは、オブジェクトperson_t('Grace', 'Hopper', 1906)
を返します。デフォルトのエラー・ハンドラはNULL ON ERROR
であるため、フィールドmiddle
は無視されます。
SELECT json_value('{"first": "Grace",
"middle": "Brewster",
"last": "Hopper",
"birthyear": "1906"}',
'$'
RETURNING person_t)
FROM DUAL;
この問合せでは、余計なデータの不一致のためにエラーが発生します。フィールドmiddle
は余計です。
SELECT json_value('{"first": "Grace",
"middle": "Brewster",
"last": "Hopper",
"birthyear": "1906"}',
'$'
RETURNING person_t
ERROR ON MISMATCH (EXTRA DATA))
FROM DUAL;
ORA-40602: extra data for object type conversion
この問合せでは、3つのON MISMATCH
句を使用します。オブジェクトperson_t('Grace', 'Hopper', NULL)
を返します。ERROR ON MISMATCH (EXTRA DATA)
句は、それ自体でエラーが発生しますが、IGNORE ON MISMATCH (TYPE ERROR)
によってそのエラーは無視されます。
SELECT json_value('{"first": "Grace",
"middle": "Brewster",
"last": "Hopper",
"birthyear": "1906"}',
'$'
RETURNING person_t
ERROR ON MISMATCH (EXTRA DATA)
ERROR ON MISMATCH (MISSING DATA)
IGNORE ON MISMATCH (TYPE ERROR))
FROM DUAL;
17.7 SQLファンクションおよび条件のTYPE句
Oracle SQLファンクションのjson_transform
、SQL/JSONファンクションの json_query
、json_value
とjson_table
およびSQL/JSON条件のjson_exists
では、オプションのTYPE
句を受け入れます。この句では、JSON値がJSON言語の型に関して厳密に(つまり、関連する"only"データ型変換項目メソッドが比較対象のデータに適用されたかのように)比較されるかどうかを指定します。
キーワードTYPE
の後に、カッコで囲んだキーワードSTRICT
またはLAX
が続きます。
-
TYPE (LAX)
は、デフォルトの動作(TYPE
句なしと同じ)を指定します。つまり、JSON値は、比較のためにSQLデータ型の値として暗黙的に解釈(実質的にキャスト)できます。この型キャストについては、「比較における型」を参照してください。たとえば、
'$.PONumber?(@ > 20)
などの比較では、PONumber
値"314"
が数値314
として暗黙的に解釈されます(数値20と比較されるため)。この比較は、式が'$.PONumber?(@.number() > 20)
の場合と同様にtrueです -
TYPE (STRICT)
は、"only"項目メソッドを適用するのと同じ効果があります。たとえば、
'$.PONumber?(@ > 20)
は'$.PONumber?(@.numberOnly() > 20)
であるかのように動作します。PONumber
値"314"
の場合、式が'$.PONumber?(@.numberOnly() > 20)
の場合と同様に比較はfalseです。
関連項目:
Oracle Database SQL言語リファレンスのJSON_QUERY
親トピック: JSON用のSQLファンクションおよび条件で使用される句
脚注の凡例
脚注1:PASSING
句で二重引用符("
)文字でSQL/JSON変数名をラップする必要があるのは、名前で大文字と小文字を区別する必要がある場合のみです。脚注2: 入力データが
JSON
データ型である場合のみ、RAW
を戻り型として使用できます。脚注3:
JSON
データ型は、データベース初期化パラメータcompatible
が20
以上である場合にのみ使用できます。