加入收藏 | 设为首页 | 会员中心 | 我要投稿 财气旺网 - 财气网 (https://www.caiqiwang.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长百科 > 正文

使用脚本确保Oracle中的数据完整性

发布时间:2021-01-30 14:04:19 所属栏目:站长百科 来源:网络整理
导读:使用触发器或脚本来维护Oracle不是为了强制实施的数据完整性是不好的做法,还是这个标志我是以糟糕的方式建模我的数据? 从对上一篇文章(Implementing User Defined Fields)的回复中,我决定要继续使用Class和Concrete继承进行设计.我希望所有SAMPLE都有一个基

使用触发器或脚本来维护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>承诺;
承诺
*
在regel 1中的FOUT:
.ORA-12008:Fout in pad voor vernieuwen van snapshot.
ORA-00001:Schending van UNIQUE-beperking(TESTT.TABLE_ABC_UFBI1).

测试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.

(编辑:财气旺网 - 财气网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!