检查一个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
假设我有两个表,如下所示。
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