How to create sql constraints in my table

一个人想着一个人 提交于 2019-12-11 09:35:32

问题


i have this table:

id | product_group_id | percentage
1  | 1                | 0.2
2  | 1                | 0.3
3  | 1                | 0.5
4  | 2                | 0.4
5  | 2                | 0.6

I want to know if there is a way to create constraints that for each product_group_id the percentage will be equal to 1 ( if product_group_id = 1 so 0.2 + 0.3 + 0.5 = 1).
For example if i will change the percentage where id = 2 to 0.8 or 0.1, the update (or insert) will fail because the sum is not 1.

Thanks in advanced.


回答1:


It would generally make more sense to enforce this sort of constraint in the API you build on top of the table to manipulate the percentages. Assuming, of course, that each product_group_id will be manipulated by at most one session at a time.

If you do really want to enforce this sort of restriction, you could create a materialized view that refreshes on commit and create a constraint on that materialized view. Something like

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.

That will allow you to insert rows that sum to 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.

and will throw an error when you try to commit changes that cause the sum to be something other than 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

Note that this is checked at commit time which is what you really need since you'll need to violate the constraint during a transaction when you want to insert multiple rows.

And, as has been pointed out, if there is the possibility of rounding errors, you probably want the CHECK constraint to allow sums that are 1 +/- some small epsilon (i.e between 0.999999 and 1.000001)



来源:https://stackoverflow.com/questions/12027207/how-to-create-sql-constraints-in-my-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!