拡張されたスカラー値を表すテキストのJSONオブジェクト
ネイティブ・バイナリJSONデータ(OSON形式)は、SQL型に対応していて、JSON標準の一部ではないスカラー型(日付など)を追加することで、JSON言語を拡張します。Oracle Databaseでは、このような非標準の値を含め、表すJSONスカラー値を表すテキストJSONオブジェクトの使用もサポートしています。
When you create native binary JSON data from textual JSON data that contains such extended objects, they can optionally be replaced with corresponding (native binary) JSON scalar values.
拡張オブジェクトの例として、{"$numberDecimal":31}
があります。これは、非標準型小数のJSONスカラー値を表し、そのように解釈されると、ネイティブ・バイナリ形式の10進数に置き換えられます。
たとえば、JSONデータ型コンストラクタJSON
を使用する場合、キーワードEXTENDED
を使用すると、テキストの入力で認識された拡張オブジェクトがネイティブ・バイナリJSONの結果では対応するスカラー値に置き換えられます。キーワードEXTENDED
を含めなければ、このような置換は発生しません。テキストの拡張JSONオブジェクトは、ネイティブ・バイナリ形式のJSONオブジェクトにそのまま変換されるだけです。
逆方向では、SQL/JSONファンクションjson_serialize
を使用してバイナリJSONデータをテキストのJSONデータ(VARCHAR2
、CLOB
またはBLOB
)としてシリアライズする場合、キーワードEXTENDED
を使用して、(ネイティブ・バイナリ)JSONスカラー値を対応するテキストの拡張JSONオブジェクトに置き換えることができます。
使用するデータベースがOracle Autonomous Databaseの場合、PL/SQLプロシージャDBMS_CLOUD.copy_collection
を使用して、Oracle NoSQL Databaseなどの一般的なNoSQLデータベースによって生成されるようなJSONデータのファイルからJSONドキュメント・コレクションを作成できます。
ejson
をプロシージャのtype
パラメータの値として使用すると、入力ファイルで認識された拡張JSONオブジェクトが、結果のネイティブ・バイナリJSONコレクションでは対応するスカラー値に置き換えられます。もう1つの方向では、ファンクションjson_serialize
をキーワードEXTENDED
とともに使用して、結果のテキストのJSONデータで、スカラー値を拡張JSONオブジェクトに置き換えることができます。
拡張オブジェクトの主なユースケースを2つ、次に示します。
-
交換(インポート/エクスポート):
-
拡張オブジェクトを含む既存のJSONデータを(どこかから)取り込む。
-
データベース外部で使用するため、拡張オブジェクトを使用して、ネイティブ・バイナリJSONデータをテキストのJSONデータのシリアライズします。
-
-
ネイティブ・バイナリJSONデータの検査: 対応する拡張オブジェクトを参照して、内容を確認します。
交換目的の場合、拡張オブジェクトをネイティブ・バイナリJSONスカラーに変換して、Oracle NoSQL Databaseなどの一般的なNoSQLデータベースによって生成されたファイルからJSONデータを取り込むことができます。もう1つの方向では、Oracle固有のスカラーJSON値を対応するテキスト拡張JSONオブジェクトに置き換えて、ネイティブ・バイナリJSONデータをテキスト・データとしてエクスポートできます。
ヒント:
検査の例としては、{"dob" : "2000-01-02T00:00:00"}
などのオブジェクトを、ネイティブJSONデータをシリアライズした結果として考えてみます。"2000-01-02T00:00:00"
は、日付型のネイティブ・バイナリ値をシリアライズした結果か、あるいは、ネイティブ・バイナリ値は単なる文字列でしょうか。json_serialize
をキーワードEXTENDED
とともに使用すると、わかります。
拡張オブジェクト・フィールドからスカラーJSON型へのマッピングとは、一般に多対1です。複数の種類の拡張JSONオブジェクトを特定のスカラー値にマップできます。たとえば、拡張JSONオブジェクトの{"$numberDecimal":"31"}
と{"$numberLong:"31"}
は、どちらも値31のJSON言語スカラー型numberとして変換され、これらの各JSONスカラーに対して項目メソッドtype()
は"number"
を返します。
項目メソッドtype()
は、対象値のJSON言語スカラー型を(JSON文字列として)報告します。スカラー値の中には、同じスカラー型であっても内部的に区別できるものがあります。これにより、通常、ファンクションjson_serialize
(キーワードEXTENDED
)による元の拡張JSONオブジェクトの再構築が可能になります。そのようなスカラーの値は、その値を実装する様々なSQL型を使用するか、導出元拡張JSONオブジェクトの種類でタグ付けすることで、内部的に区別されます。
json_serialize
で元の拡張JSONオブジェクトを再構築する場合、結果は必ずしも元のものとテキスト的同一であるとはかぎりませんが、常に意味的に同等です。たとえば、{"$numberDecimal":"31"}
と{"$numberDecimal":31}
は、フィールド値の型(文字と数値)が異なていても意味的に等しいものです。これらは同じ内部値に変換され、それぞれが$numberDecimal
拡張オブジェクト(同じタグ)から導出されたものとしてタグ付けされています。ただし、シリアライズすると、両方の結果は{"$numberDecimal":31}
になります。Oracleでは常に、最も直接関連する型がフィールド値に使用されます。この場合は、スカラー型番号のJSON言語値31
です。
表3-1に、使用される様々な型間の対応関係を示します。(1)入力として使用される拡張オブジェクトの型、(2)項目メソッドtype()
によって報告される型、(3)内部で使用されるSQL型、(4)ファンクションjson_serialize
による出力として使用される標準のJSON言語型、および(5)キーワードEXTENDED
が指定されている場合のjson_serialize
による拡張オブジェクト出力の型の間でマップします。
表3-1 拡張JSONオブジェクト型の関係
拡張オブジェクト型(入力) | Oracle JSONスカラー型(type()によって報告) | SQLスカラー型 | 標準JSONスカラー型(出力) | 拡張オブジェクト型(出力) |
---|---|---|---|---|
JSON数値、数値を表す文字列、または"Infinity" 、"-Infinity" 、"Inf" 、"-Inf" 、"Nan" 脚注1のいずれの文字列を値として持つ $numberDouble
|
double | BINARY_DOUBLE |
番号 |
$numberDouble (値はJSON数値または"Inf" 、"-Inf" 、"Nan" 脚注2)のいずれかの文字列 |
$numberDouble と同じ値を持つ$numberFloat |
float | BINARY_FLOAT |
番号 |
$numberDouble と同じ値を持つ$numberFloat |
$numberDouble と同じ値を持つ$numberDecimal |
番号 | NUMBER |
番号 |
$numberDouble と同じ値を持つ$numberDecimal |
符号付き32ビット整数または数値を表す文字列を持つ$numberInt
|
番号 | NUMBER |
番号 |
$numberDouble の場合と同じ値の$numberInt |
$numberLong (値はJSON数値または数値を表す文字列)
|
番号 | NUMBER |
番号 |
$numberDouble と同じ値を持つ$numberLong |
値がBase-64文字列の場合は、拡張オブジェクトにフィールド |
バイナリ | BLOB またはRAW |
文字列 変換は、SQLファンクション |
次のいずれかが指定されます。
|
$oid (値は24桁の16進文字列)
|
バイナリ | RAW(12) |
文字列 変換は、SQLファンクション |
$rawid (値は24桁の16進文字列)
|
偶数の16進数文字を含む文字列値を持つ$rawhex
|
バイナリ | RAW |
文字列 変換は、SQLファンクション |
$binary (値はbase-64文字列、= 文字で右詰め)
|
値が24または32桁の16進文字列の$rawid
|
バイナリ | RAW |
文字列 変換は、SQLファンクション |
$rawid |
値がISO 8601の日付文字列の$oracleDate
|
日付 | DATE |
文字列 |
値がISO 8601の日付文字列の$oracleDate
|
$oracleTimestamp (値はISO 8601のタイムスタンプ文字列)
|
時刻 | TIMESTAMP |
文字列 |
$oracleTimestamp (値はISO 8601タイムスタンプ文字列)
|
$oracleTimestampTZ (値はISO 8601タイムスタンプ文字列で、数値のタイムゾーン・オフセットまたはZ を持つ) |
タイムスタンプ(タイムゾーン) | TIMESTAMP WITH TIME ZONE |
文字列 |
$oracleTimestampTZ (値はISO 8601タイムスタンプ文字列で、数値のタイムゾーン・オフセットまたはZ を持つ) |
次のいずれかの値を持つ
|
タイムスタンプ(タイムゾーン) | TIMESTAMP WITH TIME ZONE |
文字列 |
$oracleTimestampTZ (値はISO 8601タイムスタンプ文字列で、数値のタイムゾーン・オフセットまたはZ を持つ) |
SQLファンクションto_dsinterval に指定されたISO 8601間隔文字列が値の$intervalDaySecond |
daysecondInterval | INTERVAL DAY TO SECOND |
文字列 |
SQLファンクションto_dsinterval に指定されたISO 8601間隔文字列が値の$intervalDaySecond |
$intervalYearMonth (値はSQLファンクションto_yminterval に指定されたISO 8601間隔文字列) |
yearmonthInterval | INTERVAL YEAR TO MONTH |
文字列 |
$intervalYearMonth (値はSQLファンクションto_yminterval に指定されたISO 8601間隔文字列) |
2つのフィールド:
|
ベクトル | VECTOR |
数の配列 |
2つのフィールド:
|
脚注1 文字列値は大/小文字の区別なく解釈されます。たとえば、"NAN"
、"nan"
および"nAn"
は受け入れられ、同等であり、"INF"
、"inFinity"
および"iNf"
も同様です。無限に大きい("Infinity"
または"Inf"
)および小さい("-Infinity"
または"-Inf"
)数値は、フルワードまたは略称のいずれかで受け入れられます。
脚注2 出力には、これらの文字列値のみが使用されます。完全な単語Infinityや大/小文字が異なる値はありません。
関連項目: