问题描述
我有一个存储在表中的层次结构。 每个元素都有一个指向其上一个,下一个和父级的指针
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。
但是如何在提交时调用它呢? 我不想在每次行更新时都调用它,就在提交完成之前,如果我的表无效,则有可能回滚。
1楼
如我所述,可以通过结合物化视图(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;
2楼
理想情况下,您应该编写一个100%的程序包来控制该表的维护。 如有必要,将其放在自己的架构中,锁定其特权,然后仅使用此软件包来修改表。