複数のテーブルをJOINしたViewにINSTEAD OF INSERT, UPDATE, DELETEの各トリガを仕込み、あたかもテーブルのように使わせるというアプローチは実際には限界があることがわかった。
通常のINSERT, UPDATE, DELETEは問題なく動くが、以下のUPDATE文はエラーになる。
update joinview
set field1=b.fieldx,field2=b.fieldy
from joinview a
inner join valuestbl b on b.id=a.id
メッセージ 414、レベル 16、状態 1、行 3
UPDATE は許可されません。ステートメントにより、結合に参加していて、INSTEAD OF DELETE トリガを保持しているビュー "joinview" が更新されます。
(日本語のメッセージだけ、INSTEAD OF DELETEと間違えて表示されるのがまたなんともいえないが)
この更新を認めない理由はいくら眺めても「INSTEAD OFトリガ」の項には書かれていない。しかし、「UPDATE」の項にはひっそりと以下の記述があった。
>INSTEAD OF UPDATE トリガを伴うビューは、FROM 句を伴う UPDATE の対象にはなりません。
では、他のテーブルの値で更新することはできないのかというと、以下の更新はできる。
update joinview
set field1=(select fieldx from valuestbl where id=a.id),
field2=(select fieldy from valuestbl where id=a.id)
from joinview a
JOINしてなければ、from句はあってもいいのか。。
Oracleで使える複数フィールドの一括更新の構文は使えないから、これでは煩雑だし、フィールドが増えてくるとパフォーマンス的にも心配だ。
一方、考え方を変えれば、結合更新のケースって、トランザクション処理ではほとんどのケースで回避できるのかもしれない、とも思う。あきらめるほどのこともないのか。。