4.4 二面性ビューを更新するためのルール

二面性ビューでサポートされるドキュメントを更新する場合は、一部のルールを考慮する必要があります。

  1. ドキュメント更新操作(更新、挿入または削除)が試行され、現在のユーザーまたはビュー所有者に必要な権限が付与されていない場合、試行時にエラーが発生します。(関連する権限については、「二面性ビューの更新操作に必要なデータベース権限」を参照してください。)

  2. 試行されたドキュメント更新操作(更新、挿入または削除)が二面性ビューの基礎となる表に適用されている制約に違反した場合、エラーが発生します。これには、主キー、一意キー、NOT NULLの参照整合性およびチェック制約が含まれています。

  3. ドキュメント更新操作(更新、挿入または削除)が試行され、その操作がビューの注釈で考慮されていない場合は、試行時にエラーが発生します。

  4. ドキュメントを二面性ビューに挿入する場合、ドキュメントには、(1)ドキュメントのETAG値に関与し、かつ(2)ビュー定義で更新専用または読取り専用とマークされた(ルート以外の)表の列に対応するすべてのフィールドが含まれている必要があります。また、対応する列データが表にすでに存在している必要があります。これらの条件が満たされない場合は、エラーが発生します。

    読取り専用列に対応するすべてのフィールドの値も、表内の対応する列値と一致する必要があります。そうでない場合は、エラーが発生します。

    たとえば、二面性ビューrace_dvdriver表を使用すると、更新専用(WITH NOINSERT UPDATE NODELETEの注釈付き)になります。新しいレース・ドキュメントを挿入する場合、ドキュメントにはdriver表の列driver_idおよびnameに対応するフィールドが含まれている必要があり、driver表には、そのドキュメントのドライバ情報に対応するデータがすでに含まれている必要があります。

    同様に、driver表がビューrace_dvで(更新専用ではなく)読取り専用とマークされている場合、入力ドキュメントのドライバ情報は表の既存のデータと同じである必要があります。

  5. 1対多で主キーと外部キーの関係で親にリンクされているオブジェクトを削除する場合、オブジェクトに注釈DELETEがないと、そのオブジェクトはカスケード削除されません。かわりに、オブジェクトの各行の外部キーはNULLに設定されます(外部キーにNULL値不可の制約がないとします)。

    たとえば、ビューteam_dvdriver配列はNODELETEです(DELETEに注釈が付けられていないため、暗黙的)。ビューteam_dvからチームを削除すると、対応する行が表teamから削除されます。

    ただし、driver表の対応する行は削除されません。かわりに、これらの各行は、外部キー列team_idの値をSQL NULLに設定することで、削除されたチームからリンク解除されます。

    同様に、ドライバのドキュメントは削除されません。ただし、チーム情報は削除されます。例3-2のバージョンでは、フィールドteamInfoの値が空のオブジェクト({})に設定されています。例3-3のバージョンでは、チーム・フィールドのteamIdおよびteamはそれぞれJSON nullに設定されています。

    二面性ビューteam_dvの定義での表driverの使用に注釈DELETEがあり、削除を許可するとどうなるのでしょうか。この場合、特定のチームを削除すると、ドライバもすべて削除されます。これは、driver表からこれらの行が削除され、対応するすべてのドライバ・ドキュメントも削除されることを意味します。

  6. 完全なドキュメントを置き換える更新操作では、ETAG値に関与するものとしてビューによって定義されたすべてのフィールド(つまり、注釈CHECKが適用されるすべてのフィールド)が新しい(置換)ドキュメントに含まれている必要があります。そうでない場合は、エラーが発生します。

    このルールは、演算子KEEPまたはREMOVEを使用する場合のOracle SQLファンクションjson_transformの使用にも適用されます。ETAG値に関与するフィールドがドキュメントから削除されると、エラーが発生します。

  7. 二面性ビューに同じビューの主キーまたは一意キーを参照する外部キーを持つ基礎となる表がある場合、ドキュメント更新操作(更新、挿入または削除)では、その主キーまたは一意キーの値を変更できません。これを試行すると、エラーが発生します。

  8. ドキュメント更新操作(更新、挿入または削除)に基礎となる表の同じ行の更新が含まれる場合、その行の内容は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} ]}');
  9. 更新操作(更新、挿入または削除)のために送信されるドキュメントに埋め込まれたetagフィールド値が現在のデータベース状態と一致しない場合は、エラーが発生します。

  10. ドキュメント更新操作(更新、挿入または削除)が、同じ二面性ビューでサポートされる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.