使用脚本确保Oracle中的数据完整性
使用触发器或脚本来维护Oracle不是为了强制实施的数据完整性是不好的做法,还是这个标志我是以糟糕的方式建模我的数据? 从对上一篇文章(Implementing User Defined Fields)的回复中,我决定要继续使用Class和Concrete继承进行设计.我希望所有SAMPLE都有一个基类,然后是每个唯一属性集的具体表. 虽然我可以通过使SAMPLE.sample_id成为具有外键约束的主键来强制执行每个具体表在SAMPLE中具有父条目.但是,我不知道如何强制SAMPLE条目只有一个子项,因为子条目可以在任意数量的表中. 我该如何强制执行此操作?如果解决方案是INSERT,UPDATE和DELETE触发器,这被认为是不好的做法吗? 解决方法我认为您可以通过使用物理化视图来解决这个问题,该视图是主表id上的TABLEA,TABLEB和TABLEC组合.您必须创建物化视图日志,以使其成为快速可刷新的物化视图.并且您添加了一个检查约束,当每个主表id在实例化视图中有多个行时,该约束会引发错误.Rob van Wijk在这里解释了很多关于快速可刷新mv的问题. Rob van Wijk也经常出现在stackoverflow上. 在这里,您可以阅读物化视图中检查约束的使用:http://technology.amis.nl/blog/475/introducing-materialized-views-as-mechanism-for-business-rule-implementation-complex-declarative-constraints 使用快速可刷新的mv意味着在提交期间完成完整性检查,而不是在插入或更新数据期间. 我很累,我不能自己测试,我不能提供一个真实的例子. edit1:这是一个例子: 当您使用检查约束和基于唯一函数的索引创建快速刷新mv时,它可以正常工作. 首先我们创建表: SQL> create table mastertable (id number(10) not null primary key); SQL> create table tablea (id number(10) not null primary key,master_id number(10) not null references mastertable (id)); SQL> create table tableb (id number(10) not null primary key,master_id number(10) not null references mastertable (id)); SQL> create table tablec (id number(10) not null primary key,master_id number(10) not null references mastertable (id)); 然后我们创建mv日志: SQL> create materialized view log on tablea with rowid (master_id) including new values; SQL> create materialized view log on tableb with rowid (master_id) including new values; SQL> create materialized view log on tablec with rowid (master_id) including new values; mv(真正需要umarker列!): SQL> create materialized view table_abc refresh fast with rowid on commit as select master_id,count(*) master_count,'A' umarker from tablea group by master_id union all select master_id,'B' umarker from tableb group by master_id union all select master_id,'C' umarker from tablec group by master_id / 现在我们为这个mv添加一个检查约束,以确保你不能在每个master_id的同一个详细信息表中插入两次: SQL> alter table table_abc add check (master_count in (0,1) ); 我们为此mv添加了一个基于函数的唯一索引,以确保您不能在具有相同master_id的表a和表b中插入: SQL> create unique index table_abc_ufbi1 on table_abc (case when master_count = 1 then master_id else null end); 测试1(快乐路径): SQL>插入可修饰的值(1); 1 rij是aangemaakt. SQL>插入表格值(1,1); 1 rij是aangemaakt. SQL>承诺; 提交是voltooid. 测试2(表a中的一个插入和表b中的一个插入具有相同的master_id) SQL>插入可修饰的值(2); 1 rij是aangemaakt. SQL>插入表格值(2,2); 1 rij是aangemaakt. SQL>插入tableb值(3,2); 1 rij是aangemaakt. SQL>承诺; 测试3(在表中插入两次,使用相同的master_id) SQL>插入可转换的值(3); 1 rij是aangemaakt. SQL>插入表格值(4,3); 1 rij是aangemaakt. SQL>插入表格值(5,3); 1 rij是aangemaakt. SQL>承诺;承诺*在regel 1中的FOUT:.ORA-12008:Fout in pad voor vernieuwen van snapshot.ORA-02290:CHECK-beperking(TESTT.SYS_C0015406)是geschonden. (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |