拡張されたスカラー値を表すテキストの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データ(VARCHAR2CLOBまたは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

$binary (次のいずれかの値を持つ):

  • base-64文字の文字列
  • base64フィールドとsubTypeフィールドを持つオブジェクトで、それぞれの値は、base-64文字列および数値0 (任意のバイナリ)または4 (UUID)

値がBase-64文字列の場合は、拡張オブジェクトにフィールド$subtypeを追加して、値0または4 (1バイトの整数(0-255)、または、その整数を表す2文字の16進文字列として表現)を設定することも可能です

バイナリ BLOBまたはRAW

文字列

変換は、SQLファンクションrawtohexを使用する場合と同等です。

次のいずれかが指定されます。
  • $binary (値はbase-64文字列)
  • 入力のsubType値が4 (UUID)の場合は、値が32桁の16進文字列値を持つ$rawid
$oid (値は24桁の16進文字列) バイナリ RAW(12)

文字列

変換は、SQLファンクションrawtohexを使用する場合と同等です。

$rawid (値は24桁の16進文字列)
偶数の16進数文字を含む文字列値を持つ$rawhex バイナリ RAW

文字列

変換は、SQLファンクションrawtohexを使用する場合と同等です。

$binary (値はbase-64文字列、=文字で右詰め)
値が24または32桁の16進文字列の$rawid バイナリ RAW

文字列

変換は、SQLファンクションrawtohexを使用する場合と同等です。

$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を持つ)

次のいずれかの値を持つ$date:

  • 1990年1月1日以降の整数のミリ秒数
  • ISO 8601のタイムスタンプ文字列
  • 1990年1月1日以降の整数のミリ秒カウント値を持つフィールドnumberLongを含むオブジェクト
タイムスタンプ(タイムゾーン) 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。値は、要素が数値または文字列"Nan""Inf"および"-Inf" (非数値および無限値を表す)である配列です。

  • フィールド$vectorElementType。文字列値"float32"または"float64"のいずれかです。これらはそれぞれ、IEEE 32ビットおよびIEEE 64ビットの数値に対応しています。

ベクトル VECTOR

数の配列

2つのフィールド:

  • フィールド$vector。値は、要素が数値または文字列"Nan""Inf"および"-Inf" (非数値および無限値を表す)である配列です。

  • フィールド$vectorElementType。文字列値"float32"または"float64"のいずれかです。

脚注1 文字列値は大/小文字の区別なく解釈されます。たとえば、"NAN""nan"および"nAn"は受け入れられ、同等であり、"INF""inFinity"および"iNf"も同様です。無限に大きい("Infinity"または"Inf")および小さい("-Infinity"または"-Inf")数値は、フルワードまたは略称のいずれかで受け入れられます。

脚注2 出力には、これらの文字列値のみが使用されます。完全な単語Infinityや大/小文字が異なる値はありません。