通常,在您在表顶部构建的 API 中强制执行这种约束以操纵百分比会更有意义。当然,假设每个product_group_id
会话一次最多被一个会话操作。
如果您确实想强制执行这种限制,您可以创建一个在提交时刷新的物化视图,并在该物化视图上创建一个约束。就像是
SQL> create table table_name(
2 id number primary key,
3 product_group_id number,
4 percentage number
5 );
Table created.
SQL> create materialized view log on table_name;
Materialized view log created.
SQL> ed
Wrote file afiedt.buf
1 create materialized view mv_table_name
2 refresh on commit
3 as
4 select product_group_id, sum(percentage) total_percentage
5 from table_name
6* group by product_group_id
SQL> /
Materialized view created.
SQL> alter table mv_table_name
2 add( constraint sum_of_1 check( total_percentage = 1 ));
Table altered.
这将允许您插入总和为 1 的行
SQL> insert into table_name values( 1, 1, 0.5 );
1 row created.
SQL> insert into table_name values( 2, 1, 0.5 );
1 row created.
SQL> commit;
Commit complete.
并且当您尝试提交导致总和不是 1 的更改时会引发错误
SQL> insert into table_name values( 3, 1, 0.1 );
1 row created.
SQL> commit;
commit
*
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-02290: check constraint (SCOTT.SUM_OF_1) violated
请注意,这是在提交时检查的,这是您真正需要的,因为当您想要插入多行时,您需要在事务期间违反约束。
而且,正如已经指出的那样,如果存在舍入误差的可能性,您可能希望CHECK
约束允许总和为 1 +/- 一些小 epsilon(即在 0.999999 和 1.000001 之间)