マテリアライズドビューは特別な種類のテーブルであるため、これは機能しません。データがあり、制約を適用できます。
それで、それを邪魔にならないようにしたので、混乱している基礎となるプロセスロジックを見てみましょう。テーブルに基づいたマテリアライズドビューがあります。次に、マテリアライズド・ビューに行が挿入されるたび にベース表を更新するトリガーを作成します。
マテリアライズド・ビューに変更されたデータが含まれていると思いますか?
SQLを指定した方法により、トリガー(機能する場合)はORDERSテーブルのすべての行を更新します。
トリガーはFOREACHROWであるため、マテリアライズド・ビューをリフレッシュすると、ORDERS表全体が複数回更新されます(ORDERS表の各行に対して1回)。
INSTEAD OFトリガーは、トリガーヘッダーで指定されたアクションではなく、トリガー本体のコードを実行します。したがって、(機能する可能性がある場合)トリガーはORDERSテーブルを更新し、マテリアライズド・ビューに行を挿入しません。
したがって、このエラーが、より深刻なアーキテクチャエラーの発生を妨げていることがわかると思います。あなたがする必要があるのはあなたのビジネスプロセスを明確にしそしてそれをSQLで表現しようとすることです。私の考えでは、最も適切な解決策は、ORDERSテーブルのBEFOREUPDATEトリガーです。このようなもの:
CREATE OR REPLACE TRIGGER update_ship_receive
BEFORE INSERT or UPDATE ON ORDERS
FOR EACH ROW
BEGIN
if :new.EXPECTED_SHIP_DATE is null
then
:new.EXPECTED_SHIP_DATE = :new.ORDER_DATE+5;
end if;
if :new.EXPECTED_RECEIVE_DATE is null
then
case :new.SHIPPING_METHOD
when '1 DAY' then
:new.EXPECTED_RECEIVE_DATE = :new.SHIP_DATE+1;
when '2 DAY' then
:new.EXPECTED_RECEIVE_DATE = :new.SHIP_DATE+2;
when 'GROUND' then
:new.EXPECTED_RECEIVE_DATE = :new.SHIP_DATE+5;
else
null;
end case;
end if;
END;
/
そうすれば、更新時に実行する関連処理のない単純なマテリアライズド・ビューが得られます。明らかに、実際のビジネスロジックが別のソリューションを指示する場合があります。