拡張スカラー値を表すテキスト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データ(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コレクション内の対応するスカラー値に置き換えられます。もう一方の方向では、キーワード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 |
次のいずれかの値を持つ
値がbase-64文字の文字列の場合、拡張オブジェクトには、1バイトの整数(0-255)または2文字の16進文字列として表される、値0または4のフィールド |
バイナリ | BLOB またはRAW |
文字列 変換は、SQL関数 |
次のいずれかが指定されます。
|
値が24個の16進文字の文字列の$oid
|
バイナリ | RAW(12) |
文字列 変換は、SQL関数 |
値が24個の16進文字の文字列の$rawid
|
偶数の16進文字を含む文字列の値を含む$rawhex
|
バイナリ | RAW |
文字列 変換は、SQL関数 |
$binary (値がbase-64文字の文字列、= 文字で右詰め)
|
値が24または32の16進文字の文字列の$rawid
|
バイナリ | RAW |
文字列 変換は、SQL関数 |
$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 |
次のいずれかの値を持つ
|
タイムスタンプ(タイムゾーン) | 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つのフィールド:
|
ベクトル | VECTOR |
数の配列 |
2つのフィールド:
|
脚注1 文字列値は大/小文字を区別せずに解釈されます。たとえば、"NAN"
"nan"
および"nAn"
は受け入れられ、同等であり、同様に"INF"
、"inFinity"
および"iNf"
です。無限に大きい数字("Infinity"
または"Inf"
)と小さい数字("-Infinity"
または"-Inf"
)は、単語全体または略称のいずれかで受け入れられます。
脚注2 出力では、これらの文字列値のみが使用されます。フルワードのInfinityまたは大文字小文字のバリアントは使用されません。