4.4 二面性ビューを更新するためのルール
二面性ビューでサポートされるドキュメントを更新する場合は、一部のルールを考慮する必要があります。
-
ドキュメント更新操作(更新、挿入または削除)が試行され、現在のユーザーまたはビュー所有者に必要な権限が付与されていない場合、試行時にエラーが発生します。(関連する権限については、「二面性ビューの更新操作に必要なデータベース権限」を参照してください。)
-
試行されたドキュメント更新操作(更新、挿入または削除)が二面性ビューの基礎となる表に適用されている制約に違反した場合、エラーが発生します。これには、主キー、一意キー、
NOT NULLの参照整合性およびチェック制約が含まれています。 -
ドキュメント更新操作(更新、挿入または削除)が試行され、その操作がビューの注釈で考慮されていない場合は、試行時にエラーが発生します。
-
ドキュメントを二面性ビューに挿入する場合、ドキュメントには、(1)ドキュメントのETAG値に関与し、かつ(2)ビュー定義で更新専用または読取り専用とマークされた(ルート以外の)表の列に対応するすべてのフィールドが含まれている必要があります。また、対応する列データが表にすでに存在している必要があります。これらの条件が満たされない場合は、エラーが発生します。
読取り専用列に対応するすべてのフィールドの値も、表内の対応する列値と一致する必要があります。そうでない場合は、エラーが発生します。
たとえば、二面性ビュー
race_dvでdriver表を使用すると、更新専用(WITH NOINSERT UPDATE NODELETEの注釈付き)になります。新しいレース・ドキュメントを挿入する場合、ドキュメントにはdriver表の列driver_idおよびnameに対応するフィールドが含まれている必要があり、driver表には、そのドキュメントのドライバ情報に対応するデータがすでに含まれている必要があります。同様に、
driver表がビューrace_dvで(更新専用ではなく)読取り専用とマークされている場合、入力ドキュメントのドライバ情報は表の既存のデータと同じである必要があります。 -
1対多で主キーと外部キーの関係で親にリンクされているオブジェクトを削除する場合、オブジェクトに注釈
DELETEがないと、そのオブジェクトはカスケード削除されません。かわりに、オブジェクトの各行の外部キーはNULLに設定されます(外部キーにNULL値不可の制約がないとします)。たとえば、ビュー
team_dvのdriver配列はNODELETEです(DELETEに注釈が付けられていないため、暗黙的)。ビューteam_dvからチームを削除すると、対応する行が表teamから削除されます。ただし、
driver表の対応する行は削除されません。かわりに、これらの各行は、外部キー列team_idの値をSQLNULLに設定することで、削除されたチームからリンク解除されます。同様に、ドライバのドキュメントは削除されません。ただし、チーム情報は削除されます。例3-2のバージョンでは、フィールド
teamInfoの値が空のオブジェクト({})に設定されています。例3-3のバージョンでは、チーム・フィールドのteamIdおよびteamはそれぞれJSONnullに設定されています。二面性ビュー
team_dvの定義での表driverの使用に注釈DELETEがあり、削除を許可するとどうなるのでしょうか。この場合、特定のチームを削除すると、ドライバもすべて削除されます。これは、driver表からこれらの行が削除され、対応するすべてのドライバ・ドキュメントも削除されることを意味します。 -
完全なドキュメントを置き換える更新操作では、ETAG値に関与するものとしてビューによって定義されたすべてのフィールド(つまり、注釈
CHECKが適用されるすべてのフィールド)が新しい(置換)ドキュメントに含まれている必要があります。そうでない場合は、エラーが発生します。このルールは、演算子
KEEPまたはREMOVEを使用する場合のOracle SQLファンクションjson_transformの使用にも適用されます。ETAG値に関与するフィールドがドキュメントから削除されると、エラーが発生します。 -
二面性ビューに同じビューの主キーまたは一意キーを参照する外部キーを持つ基礎となる表がある場合、ドキュメント更新操作(更新、挿入または削除)では、その主キーまたは一意キーの値を変更できません。これを試行すると、エラーが発生します。
-
ドキュメント更新操作(更新、挿入または削除)に基礎となる表の同じ行の更新が含まれる場合、その行の内容は2つの異なる方法で変更することはできません。そうでない場合は、エラーが発生します。
たとえば、
driver表の同じ行(主キーdriver_id値が105の行)のドライバnameを"George Russell"と"Lewis Hamilton"の両方にすることはできないため、この挿入の試行は失敗します。INSERT INTO team_dv VALUES ('{"_id" : 303, "name" : "Mercedes", "points" : 0, "driver" : [ {"driverId" : 105, "name" : "George Russell", "points" : 0}, {"driverId" : 105, "name" : "Lewis Hamilton", "points" : 0} ]}'); -
更新操作(更新、挿入または削除)のために送信されるドキュメントに埋め込まれた
etagフィールド値が現在のデータベース状態と一致しない場合は、エラーが発生します。 -
ドキュメント更新操作(更新、挿入または削除)が、同じ二面性ビューでサポートされる2つ以上のドキュメントに影響する場合は、基礎となる表の特定の行のデータに対するすべての変更に互換性がある(一致している)必要があります。そうでない場合は、エラーが発生します。たとえば、ドライバごとに、この操作は最初のレースの名前(
$.race[0].name)をドライバの名前($.name)に設定しようとします。UPDATE driver_dv SET data = json_transform(data, SET '$.race[0].name' = json_value(data, '$.name'));ERROR at line 1:ORA-42605: Cannot update JSON Relational Duality View 'DRIVER_DV': cannot modify the same row of the table 'RACE' more than once.
親トピック: 更新可能なJSONリレーショナル二面性ビュー