代码之家  ›  专栏  ›  技术社区  ›  Oleg Pavliv

使用触发器确保数据一致性

  •  1
  • Oleg Pavliv  · 技术社区  · 16 年前

    我有一个存储在表中的层次结构。每个元素都有一个指向上一个、下一个和父元素的指针

    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。

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

    2 回复  |  直到 16 年前
        1
  •  2
  •   Tony Andrews    16 年前

    可以通过物化视图(mv)和对mv的约束(如我所述)的组合来实现这一点。 here in my blog .

    其思想是创建一个仅包含规则例外的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
  •  1
  •   DCookie    16 年前

    理想情况下,您应该编写一个100%控制维护该表的包。如有必要,将其放入自己的模式中,锁定其权限,并仅使用此包修改表。