且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在我的表中创建sql约束

更新时间:2023-12-01 14:52:04

在您构建在表顶部的API中强制实施此类约束通常更有意义,百分比。假设每个 product_group_id 每次最多只能处理一个会话。

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.

这将允许您插入总和为1的行

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.

并且,如已经指出的,如果存在舍入错误的可能性,则可能需要 CHECK 约束,以允许为1 +/-一些小的ε(即在0.999999和1.000001之间)的和

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)