ネイティブJSONのサポート

Oracle Database 21cでは、ネイティブJavaScript Object Notation (JSON)データ型が追加されています。ODP.NET Core、管理対象ドライバおよび管理対象外ドライバは、バージョン21以降、このネイティブJSONデータ型をサポートしています。

ODP.NETでは、データベースJSONデータ型を取得したり、データベースに渡すことができます。.NET StringまたはOracleStringを使用する場合、OracleDbType.Json列挙値を使用してパラメータとしてバインドできます。この列挙値は、クライアント側でネイティブOracle Database JSONバイナリ形式OSONとの間でデコードおよびエンコードを実行し、サーバー側からタスクをオフロードするようにODP.NETに指示します。

あるいは、JSONデータをパラメータとして他のODP.NETおよび.NETデータ型にバインドすることも、OracleDbType.Json列挙値を使用しないこともできます。このような場合、クライアントではなく、Oracle DatabaseがOSONへのエンコードと、OSONから目的のデータ型形式へのデコードを暗黙的に行います。DataSetでは、Oracle JSONタイプが変換されて、.NET文字列またはOracleStringのいずれかとして格納されます。

管理対象ODP.NETおよびODP.NET Core JSONの機能では、System.Text.Jsonアセンブリをプロジェクトの依存関係として含める必要があります。ODP.NETは、依存関係自体としてSystem.Text.Jsonパッケージを追加しません。多くの場合、.NET Core 3.1以降では、このアセンブリが.NETランタイムに自動的に含まれますが、.NET Framework 4.8には含まれません。

管理対象外ODP.NETには、System.Text.Jsonの要件はありません。

JSON数値

管理対象ODP.NETおよびODP.NET Coreの場合、OracleDbType.Json 入力パラメータとしてバインドされたJSONドキュメントには、数値に対して28精度の上限があります。それ以外の場合は、データベースとの間で送受信されるときに、JSON数値に対して最大38精度が保持されます。

管理対象外ODP.NETでは、データベースと同様に、最大38精度のJSON数値がサポートされます。

OracleDbType.JsonとしてバインドされたJSONドキュメントに、保持できる精度より高い精度の数値が含まれている場合、ODP.NETはサポートされている最大精度に値を丸めます。最大値を超える精度を保持する必要がある場合は、JSONドキュメントを入力パラメータとしてバインドする前に、JSON値を二重引用符で囲んで数値を文字列として格納します。

JSONリレーショナル二面性

JSONリレーショナル二面性は、Oracle Database 23cで導入された画期的な機能であり、Oracle Database開発者に革新的な柔軟性と簡潔性さを提供します。この画期的革新により、リレーショナル・モデルまたはドキュメント・モデルを使用してアプリケーションを構築する際に開発者が直面していた、過去の課題を克服できます。

JSONリレーショナル二面性では、リレーショナル表とJSONドキュメントの両方の利点を備えたソリューションが提供され、どちらかのモデルのトレードオフにはなりません。

データベース内では、JSONリレーショナル二面性は、リレーショナル・データに関する十分に更新可能なJSONビューとして現れます。これらのビューは、JSONリレーショナル二面性ビューと呼ばれます。

関連項目:

この機能の詳細は、『Oracle Database JSONリレーショナル二面性開発者ガイド』を参照してください。

ODP.NETとJSONリレーショナル二面性ビュー

すべてのODP.NETプロバイダ・タイプ(Core、管理対象および管理対象外)では、JSONリレーショナル二面性ビューの使用がサポートされています。ODP.NETでは、リリース19c以降でこの機能がサポートされています。

21c以上のODP.NETでは、パラメータがOracleDbType.JSON列挙値にバインドされている場合に、このJSONデータを.NET文字列またはOracleStringデータ型として取得できます。

ODP.NET 19cでは、この列挙値を含まない以前の実装が使用されます。この場合は、JSONデータがBLOBデータ型としてフェッチされた後、.NETでの文字列に変換されます。JSONリレーショナル二面性の使用時は、ODP.NETでOracleDataReaderGetValue(s)またはGetOracleValue(s)メソッドを使用してデータが取得されます。GetStringGetOracleStringではありません。

このデータ型変換および変更は、ODP.NET開発者に対して透過的です。.NETのデータの管理で必要なのは、.NETではJSONからなる文字列としてデータを扱うということのみです。

Oracle JSONデータは、.NETのDataSetでも使用および操作できます。DataSetからOracle Databaseに変更内容を保存すると、デフォルトで生成されたOracleCommandBuilder挿入操作が正常に完了します。ただし、デフォルトの更新および削除では、これらのJSONデータを変更するために、パラメータをバインドしたカスタムSQLが必要になります。これらのJSON更新および削除を実行する方法のコード・スニペットを次に示します。

// “JRDVIEW” is the JSON Relational Duality View being updated in the example below
// Custom UPDATE SQL
string customUpdateSQL = @"UPDATE JRDVIEW SET data = :updatedJSON where json_value(data, '$.ID.number()') = json_value(:DBData, '$.ID.number()')";
adapter.UpdateCommand = new OracleCommand(customUpdateSQL, conn);
// Parameter bound to the updated data
adapter.UpdateCommand.Parameters.Add("updatedJSON", OracleDbType.Json, 100, "data"); 
// Parameter bound to row on DB
adapter.UpdateCommand.Parameters.Add("DBData", OracleDbType.Varchar2, 100, "data").SourceVersion = DataRowVersion.Original; 

// Custom DELETE SQL
string customDeleteSQL = @"DELETE FROM JRDVIEW WHERE json_value(data, '$.ID.number()') = json_value(:DBData, '$.ID.number()')";
adapter.DeleteCommand = new OracleCommand(customDeleteSQL, conn);
// Parameter bound to row on DB
adapter.DeleteCommand.Parameters.Add("DBData", OracleDbType.Varchar2, 100, "data").SourceVersion = DataRowVersion.Original; 

adapter.Update(ds);

前述のサンプル・コードでは、IDフィールドは数値型です。それが数値であることを示すには、SQL内でそれに.number()を追加します。必ずそのようにする必要があるわけではありません。しかしながら、それによってもたらされる主な利点として、問合せで実表の索引を活用できるようになるため実行パフォーマンスが向上することが挙げられます。その他のデータ型を指定できます:

  • stringデータ型の場合は.string()

  • dateデータ型の場合は.date()

  • timestampデータ型の場合は.timestamp()

ノート:

DataSetを変更するときは、_metadataメンバーやその構成要素を変更しないでください。そのメタデータは、内容を保証しない書込みがデータベースに対して実行されないようにするために使用されます。