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。

但是我怎么能在提交时调用它呢?我不想在每次行更新时都调用它,就在提交完成之前,如果我的表无效,则有可能回滚。

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 回答