web-dev-qa-db-ja.com

降順のインデックスを使用して、Oracleテーブル全体でキー保存ビューを作成する

まったく同じキー構造を持つ2つのOracleテーブルの間に更新可能なビューを作成しようとしています。既存のテーブルは、ERPシステムと、

  • 主キーがない-一意のインデックスのみ。
  • すべてのフィールドは非ヌルですが、複合インデックスフィールドの1つが降順です。

これらの2つのテーブルにわたって更新可能なビューを作成する方法はありますか?

関連する実際のテーブルには多くのデータが含まれており、頻繁に使用されるため、インデックスへの変更/追加には大幅な回帰テストが必要になるため、ビュー自体の解決策を制限する必要があります。

問題は、降順のKEY2フィールドに対して個別の複合関数ベースのインデックスを作成するOracleと関係があるようです。私はいくつかのヒントをビューに投げ込もうとしましたが、ここでは自分の深さから外れており、私が何をしているのか本当によくわかりません。

これは簡単な例です。 2つのKEY2インデックスフィールドから「desc」を削除すると、最終的な更新が機能します-そのままにすると、「ORA-01779:非キー保存テーブルにマップする列を変更できません」というエラーが発生します。

create table TEST_KEY_PRES_A (
   KEY1 varchar2(8) not null,
   KEY2 varchar2(8) not null,
   VAL1 smallint not null,
   VAL2 varchar2(8) not null
)
;

create unique index TEST_KEY_PRES_A_IDX
on TEST_KEY_PRES_A (KEY1, KEY2 desc)
;

insert into TEST_KEY_PRES_A values ('K11', 'K21', 1, 'V2-1');
insert into TEST_KEY_PRES_A values ('K15', 'K25', 5, 'V2-5');

create table TEST_KEY_PRES_B (
   KEY1 varchar2(8) not null,
   KEY2 varchar2(8) not null,
   VAL3 varchar2(8) not null
)
;

create unique index TEST_KEY_PRES_B_IDX
on TEST_KEY_PRES_B (KEY1, KEY2 desc)
;

insert into TEST_KEY_PRES_B values ('K11', 'K21', 'V3-1');
insert into TEST_KEY_PRES_B values ('K15', 'K25', 'V3-5');

create view TEST_KEY_PRES_VW (KEY1, KEY2, VAL1, VAL2, VAL3) AS
select pa.KEY1, pa.KEY2, pa.VAL1, pa.VAL2, pb.VAL3
from   TEST_KEY_PRES_A pa
join   TEST_KEY_PRES_B pb on pa.KEY1 = pb.KEY1 and pa.KEY2 = pb.KEY2
where  pa.VAL1 > 3
;

update TEST_KEY_PRES_VW
set    VAL2 = 'V2-5-X'
where  KEY1 = 'K15'
;

[〜#〜]解決済み[〜#〜]

Eduardによって提案されたINSTEAD OFトリガーの使用:

create or replace trigger TEST_KEY_PRES_VW_UPD_TR
instead of update on TEST_KEY_PRES_VW
for each row
begin
    update TEST_KEY_PRES_A
    set    VAL1 = :new.VAL1, VAL2 = :new.VAL2
    where  KEY1 = :new.KEY1 and KEY2 = :new.KEY2;

    update TEST_KEY_PRES_B
    set    VAL3 = :new.VAL3
    where  KEY1 = :new.KEY1 and KEY2 = :new.KEY2;
end;
1
Barney

ビューを作成する必要がなく、結合を使用して更新するだけの場合は、MERGEステートメントで回避策を使用できます。

merge into TEST_KEY_PRES_A pa 
using TEST_KEY_PRES_B pb
  on (pa.KEY1 = pb.KEY1 and pa.KEY2 = pb.KEY2 and pa.VAL1 > 3 and pa.KEY1 = 'K15')
 when matched then update
   set VAL2 = 'V2-5-X';
1
Eduard Okhvat