拡張されたスケール値を表すテキストのJSONオブジェクト

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

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

拡張オブジェクトの例は、{"$numberDecimal":31}です。これは、非標準型の10進数のJSONスカラー値を表し、そのように解釈されると、ネイティブ・バイナリ形式の小数に置き換えられます。

たとえば、JSONデータ型コンストラクタJSONを使用する場合、キーワードEXTENDEDを使用すると、テキスト入力で認識された拡張オブジェクトがネイティブ・バイナリJSONの結果では対応するスカラー値に置き換えられます。キーワードEXTENDEDを含めなければ、このような置換は発生しません。テキストの拡張JSONオブジェクトは、ネイティブ・バイナリ形式のJSONオブジェクトにそのまま変換されるだけです。

逆方向では、Oracle SQLファンクション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コレクションでは対応するスカラー値に置き換えられます。逆に、ファンクションjson_serializeをキーワードEXTENDEDとともに使用して、結果のテキストJSONデータの拡張JSONオブジェクトにスカラー値を置換できます。

拡張オブジェクトの主なユースケースは、次の2つです:

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

    • 拡張オブジェクトを含む既存のJSONデータを(任意の場所から)収集します。

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

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

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

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

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

ノート

内部バイナリJSON値を導出する際に、元の拡張オブジェクトの型が損失する可能性のあるケースが2つあります。

  • フィールド$numberIntを持つ拡張オブジェクトが、タグなしでOracle SQL NUMBER内部値に変換されます。その値をシリアライズすると、数値型の標準JSON言語値が生成されます。数値に損失はありません。唯一の損失は、元のテキスト・データが$numberInt拡張オブジェクトであったという情報です。

  • フィールド$numberDecimalを無限値、非常に小さい値、非常に大きい値または非数値とともに使用することはサポートされていないため、未定義の動作が発生します。使用しないでください正の無限大("Infinity"または"Inf")、負のインフィニティ("-Infinity"または"-Inf")または不明な値(非数値、"Nan")を表す文字列値を$numberDecimalとともに使用してください — かわりに、このような値には$numberDoubleを使用してください。

表3-1に、使用される様々な型の間の対応関係を示します。(1)入力として使用される拡張オブジェクトの型、(2)アイテム・メソッドtype()によって報告される型、(3)内部で使用されるSQL型、(4)ファンクションjson_serializeによる出力として使用される標準のJSON言語型、および(5)キーワードEXTENDEDが指定されている場合のjson_serializeによる拡張オブジェクト出力の型の間でマップします。

表3-1拡張JSONオブジェクト型の関係

拡張オブジェクト型(入力) Oracle JSONスカラー型(type()によるレポート) SQLスカラー型 標準JSONスカラー型(出力) 拡張オブジェクト型(出力)
$numberDouble (値はJSON数値、数値を表す文字列、または"Infinity""-Infinity""Inf""-Inf""Nan"のいずれかの文字列脚注1) double BINARY_DOUBLE

数値

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

数値

$numberDoubleと同じ値の$numberFloat
$numberDoubleと同じ値の$numberDecimal 数値 NUMBER

数値

$numberDoubleと同じ値の$numberDecimal
$numberInt (値は署名付き32ビット整数または数値を表す文字列) 数値 NUMBER

数値

$numberInt ($numberDoubleと同じ値を持つ)
値がJSON数値または数値を表す文字列の$numberLong 数値 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

string

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

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

string

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

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

string

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

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

string

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

$rawid
値がISO 8601日付文字列の$oracleDate 日付 DATE

string

値がISO 8601日付文字列の$oracleDate
$oracleTimestamp (値はISO 8601タイムスタンプ文字列) timestamp TIMESTAMP

string

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

string

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

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

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

string

$oracleTimestampTZ (値はISO 8601タイムスタンプ文字列で、数値のタイムゾーン・オフセットまたはZを持つ)
$intervalDaySecond (値はSQLファンクションto_dsintervalに指定されたISO 8601間隔文字列) daysecondInterval INTERVAL DAY TO SECOND

string

$intervalDaySecond (値はSQLファンクションto_dsintervalに指定されたISO 8601間隔文字列)
$intervalYearMonth (値はSQLファンクションto_ymintervalに指定されたISO 8601間隔文字列) yearmonthInterval INTERVAL YEAR TO MONTH

string

$intervalYearMonth (値はSQLファンクションto_ymintervalに指定されたISO 8601間隔文字列)

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

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