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

时间:2012-08-19 14:20:34

标签: sql oracle constraints oracle-sqldeveloper

我有这张桌子:

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

我想知道是否有办法创建约束,每个product_group_id的百分比等于1(如果product_group_id = 1,那么0.2 + 0.3 + 0.5 = 1)。
例如,如果我将id = 2的百分比更改为0.8或0.1,则更新(或插入)将失败,因为总和不是1.

先谢谢了。

1 个答案:

答案 0 :(得分:4)

在您在表格顶部构建的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之间)< / p>