2010-06-30 60 views
1

我有一個分層結構存儲在一個表中。每一個元素都有一個指針到其先前的,下一個和母使用觸發器確保數據一致性

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

我有一個Java應用程序,其使用O/R映射來訪問和修改該表。有時我的目錄被損壞,例如它們是不具有相同父代的鏈接元素。我想知道是否可以使用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

但我怎麼能調用它承諾?我不想在每次行更新時調用它,就在提交完成之前,如果我的表無效,可能會回滾。

+0

「又聯繫不具有相同的父元素」怎麼可能觸發過確定什麼是「同一個父」可能是什麼意思? – 2010-06-30 15:23:47

+0

@ S.Lott:我添加了一些信息,以便更清楚。 – 2010-06-30 15:30:37

回答

2

它可能會通過物化視圖(MV)和如我所描述here in my blog對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; 
+0

託尼,非常感謝。 – 2010-07-01 08:11:42

1

理想情況下,您應該編寫一個100%控制維護此表的包。如果有必要,將它放在它自己的模式中,鎖定它的權限,並使用這個包來修改表。

+0

感謝您的回答。正如我之前解釋的,我有一個Java應用程序。更確切地說,一個錯誤的Java應用程序。我想使用純SQL來避免數據庫中的不一致。但我不想將業務邏輯的實現從Java切換到SQL。 – 2010-06-30 20:05:18

+0

我會提供相同的建議,只是在java窗體中 - 有一個java類來處理這個表的維護。使用它很難實施,但對於這個至關重要的事情,您需要集中控制。否則,你將永遠在尋找錯誤。我不知道您的應用程序中的活動級別,但其他解決方案將涉及額外的開銷。祝你好運,+1有趣的問題... – DCookie 2010-06-30 21:08:34