1

テーブルに格納された階層構造があります。各要素には、その前、次、および親へのポインターがあります

create table CATALOGUE
(
  NAME VARCHAR2(300) not null,
  NEXT_ID NUMBER(38),
  PARENT_ID NUMBER(38),
  PREVIOUS_ID NUMBER(38),
  XID NUMBER(38)
);

O/R マッピングを使用してこのテーブルにアクセスして変更する Java アプリケーションがあります。カタログが破損することがあります。たとえば、同じ親を持たないリンクされた要素です。Oracleトリガーまたは他の純粋なSQL手法(Javaコードなし)を使用してデータの一貫性を確保できるかどうか疑問に思っています。

これは物事を行う「正しい方法」ですか?

トリガーを実装するにはどうすればよいですか? テーブルを検証するストアド プロシージャを実装できます。何かのようなもの

select count(*) 
from catalogue c1, catalogue c2 
where c1.next_id = c2.previous_id and c1.parent_id != c2.parent_id

0 を返す必要があります。

しかし、コミット時にどのように呼び出すことができますか? テーブルが有効でない場合にロールバックする可能性があるコミットが終了する直前に、すべての行の更新でそれを呼び出したくありません。

4

2 に答える 2

2

ブログで説明したように、マテリアライズド ビュー (MV) と MV の制約を組み合わせることで、これを強制できる場合があります。

アイデアは、ルールの例外のみを保持する MV を作成し、行が MV に入力されたときに常に失敗する制約を持つことです。このようなもの:

create materialized view check_mv
refresh complete on commit as
select 1 dummy
from catalogue c1, catalogue c2 
where c1.next_id = c2.previous_id and c1.parent_id != c2.parent_id

alter table check_mv
add constraint check_mv_chk
check (1=0) deferrable;
于 2010-06-30T16:21:15.107 に答える
1

理想的には、このテーブルの保守を100%制御できるパッケージを作成する必要があります。必要に応じて、それを独自のスキーマに配置し、そのスキーマに対する特権をロックダウンし、このパッケージのみを使用してテーブルを変更します。

于 2010-06-30T19:59:03.493 に答える