检查一个table(列)的日期是否适合另一个table(列)的日期

Check constraint whether the date from one table (column) fits to another date from another table (column)

假设我有两个表,如下所示。

create table contract(
 c_ID       number(1) primary key,
 c_name     varchar2(50) not null,
 start        date not null,
 end          date not null,
 d_ID       number(1) null,
 constraint fk_discount_ID
 foreign key(d_ID) references discount(d_ID)
);

create table discount(
 d_ID   number(1) primary key not null,
 d_amount decimal(4,2) not null,
 valid_from    date,
 valid_until   date
);

现在我想添加一个约束来检查折扣在合同开始日期是否有效。例如,合同于2015年5月1日开始,折扣有效期至2015年4月30日,不适用于上述合同。

我该如何做这个约束?

很遗憾,您无法使用约束执行如此复杂的验证。

虽然有一种方法可以结合使用物化视图 约束(参见 my blog),但实际上我们通常不会这样做不利的性能影响。

触发器是一种选择,但我会避免使用它们,因为它们很难正确使用,因此它们在多用户系统中始终可以正常工作。

这留下了最常见的方法(根据我的经验):为您的交易构建 PL/SQL APIs 来执行业务规则,而不是简单地在 [=12= 中插入一行] 应用程序这样调用 API:

contract_api.create_contract 
   ( p_name => :name
   , p_start => :start
   , p_d_id => :d_id
   ...
   );

API 在插入之前验证业务规则,因此此调用可能会失败并出现如下异常:

ORA-20001: Discount not valid on contract start date