【问题标题】:How to create sql constraints in my table如何在我的表中创建 sql 约束
【发布时间】:2012-08-20 01:35:36
【问题描述】:

我有这张桌子:

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/3呢?这个数字以百分比表示时会四舍五入,因此不可能达到 1。
  • @Andre 你是什么意思?
  • @Offer 你将不得不处理舍入错误。
  • 您使用的是什么数据库?创建与此表关联的触发器以检查约束。
  • 如何在组中添加第一行?

标签: sql oracle constraints oracle-sqldeveloper


【解决方案1】:

在您构建于表之上的 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 之间)

【讨论】:

    猜你喜欢
    • 2021-06-11
    • 2015-12-10
    • 2013-05-21
    • 2010-12-22
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 2012-07-30
    相关资源
    最近更新 更多