假设我有以下两个表。
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日有效,不能适用于上述合同。
我怎么能做这个约束?
答案 0 :(得分:4)
不幸的是,你无法使用约束来执行这种复杂的验证。
虽然有一种方法可以使用物化视图和约束(参见my blog)的组合,但实际上我们通常不这样做,因为它可能会对性能产生负面影响。< / p>
触发器是一种选择,但我会避免它们,因为它们很难正确,因此它们始终可以在多用户系统中正常工作。
这留下了最常见的方法(根据我的经验):为您的事务构建PL / SQL API以强制执行业务规则,以便不是简单地在contract
中插入行,而是应用程序调用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