拡張スカラー値を表すテキストJSONオブジェクト

ネイティブ・バイナリJSONデータ(OSON形式)は、SQL型に対応し、JSON標準の一部ではないスカラー型(日付など)を追加することで、JSON言語を拡張します。Oracle Databaseでは、JSONスカラー値を表すテキストJSONオブジェクト(このような非標準値を含む)の使用もサポートされています。

このような拡張オブジェクトを含むテキストJSONデータからネイティブ・バイナリJSONデータを作成する場合、オプションで、対応する(ネイティブ・バイナリ)JSONスカラー値とともに置換できます。

拡張オブジェクトの例は、{"$numberDecimal":31}です。これは、非標準型10進数の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コレクション内の対応するスカラー値に置き換えられます。もう一方の方向では、キーワードEXTENDEDを持つファンクションjson_serializeを使用して、スカラー値を、結果のテキストJSONデータの拡張JSONオブジェクトに置き換えることができます。

拡張オブジェクトの2つの主なユースケースを次に示します。

  • 交換(インポート/エクスポート):

    • 拡張オブジェクトを含む既存のJSONデータを(どこからでも)取り込みます。

    • データベース外部で使用するために、ネイティブ・バイナリJSONデータを拡張オブジェクトを含むテキストJSONデータとしてシリアライズします。

  • ネイティブ・バイナリJSONデータの検査: 対応する拡張オブジェクトを参照して、何があるかを確認します。

交換のために、Oracle NoSQL Databaseなどの一般的なNoSQLデータベースによって生成されたファイルからJSONデータを取り込み、拡張オブジェクトをネイティブ・バイナリJSONスカラーに変換できます。逆に、ネイティブ・バイナリJSONデータをテキスト・データとしてエクスポートし、Oracle固有のスカラーJSON値を対応するテキスト拡張JSONオブジェクトに置き換えることができます。

ヒント:

検査の例として、ネイティブJSONデータをシリアライズした結果として、{"dob" : "2000-01-02T00:00:00"}などのオブジェクトを考えてみます。"2000-01-02T00:00:00"は、date型のネイティブ・バイナリ値をシリアライズした結果ですか、それともネイティブ・バイナリ値は単なる文字列ですか。json_serializeをキーワードEXTENDEDとともに使用すると、わかります。

拡張オブジェクト・フィールドからスカラーJSON型へのマッピングは、通常、多対1です。複数の種類の拡張JSONオブジェクトを特定のスカラー値にマップできます。たとえば、拡張JSONオブジェクト{"$numberDecimal":"31"}および{"$numberLong:"31"}は、両方ともJSON言語スカラー型番号の値31として変換され、項目メソッドtype()は、これらのJSONスカラーごとに"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

番号

JSON数値、または"Inf""-Inf""Nan"脚注2のいずれかの文字列を持つ$numberDouble
$numberDoubleと同じ値を持つ$numberFloat float BINARY_FLOAT

番号

$numberDoubleと同じ値を持つ$numberFloat
$numberDoubleと同じ値を持つ$numberDecimal 番号 NUMBER

番号

$numberDoubleと同じ値を持つ$numberDecimal
$numberInt (符号付き32ビット整数または数値を表す文字列) 番号 NUMBER

番号

$numberDoubleと同じ値を持つ$numberInt
値にJSON番号または数値を表す文字列を指定した$numberLong 番号 NUMBER

番号

$numberDoubleと同じ値を持つ$numberLong

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

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

値がbase-64文字の文字列の場合、拡張オブジェクトには、1バイトの整数(0-255)または2文字の16進文字列として表される、値0または4のフィールド$subtypeを含めることもできます。

バイナリ BLOBまたはRAW

文字列

変換は、SQL関数rawtohexの使用と同等です。

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

文字列

変換は、SQL関数rawtohexの使用と同等です。

値が24個の16進文字の文字列の$rawid
偶数の16進文字を含む文字列の値を含む$rawhex バイナリ RAW

文字列

変換は、SQL関数rawtohexの使用と同等です。

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

文字列

変換は、SQL関数rawtohexの使用と同等です。

$rawid
ISO 8601日付文字列の値を持つ$oracleDate 日付 DATE

文字列

ISO 8601日付文字列の値を持つ$oracleDate
ISO 8601タイムスタンプ文字列の値を持つ$oracleTimestamp 時刻 TIMESTAMP

文字列

ISO 8601タイムスタンプ文字列の値を持つ$oracleTimestamp
数値のタイムゾーン・オフセットまたはZを使用したISO 8601タイムスタンプ文字列を持つ$oracleTimestampTZ タイムスタンプ(タイムゾーン) TIMESTAMP WITH TIME ZONE

文字列

数値のタイムゾーン・オフセットまたはZを使用したISO 8601タイムスタンプ文字列を持つ$oracleTimestampTZ

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

  • 1990年1月1日以降のミリ秒単位の整数カウント
  • ISO 8601タイムスタンプ文字列
  • 1990年1月1日以降、値がミリ秒の整数カウントのフィールドnumberLongを持つオブジェクト
タイムスタンプ(タイムゾーン) TIMESTAMP WITH TIME ZONE

文字列

数値のタイムゾーン・オフセットまたはZを使用したISO 8601タイムスタンプ文字列を持つ$oracleTimestampTZ
SQL関数to_dsintervalに指定されたISO 8601間隔文字列の値を持つ$intervalDaySecond daysecondInterval INTERVAL DAY TO SECOND

文字列

SQL関数to_dsintervalに指定されたISO 8601間隔文字列の値を持つ$intervalDaySecond
SQL関数to_ymintervalに指定されたISO 8601間隔文字列の値を持つ$intervalYearMonth yearmonthInterval INTERVAL YEAR TO MONTH

文字列

SQL関数to_ymintervalに指定されたISO 8601間隔文字列の値を持つ$intervalYearMonth

2つのフィールド:

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

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

ベクトル VECTOR

数の配列

2つのフィールド:

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

  • 文字列値が"float32"または"float64"のフィールド$vectorElementType

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

脚注2 出力では、これらの文字列値のみが使用されます。フルワードのInfinityまたは大文字小文字のバリアントは使用されません。