我们假设我有一张桌子:
CREATE TABLE "STACK_OVERFLOW_QUESTION"
(
"SSN" VARCHAR2(13 BYTE) NOT NULL ENABLE,
"IRN" VARCHAR2(11 BYTE) NOT NULL ENABLE,
"BEGIN_DATE" DATE,
"END_DATE" DATE
)
我需要一个唯一的索引来强制执行一个策略,在该策略中,从BEGIN_DATE到END_DATE的间隔之间不能有相同的SSN和IRN。例如,让我们假设表中有这些行:
| SSN | IRN | BEGIN_DATE | END_DATE |
|------------|-------------|--------------|-------------|
| 565654 | 154646678 | 01/01/2010 | 01/02/2010 | - (first row inserted) OK
| 565654 | 154646678 | 03/04/2010 | 20/04/2010 | - (second row inserted) OK
| 565654 | 154646678 | 28/01/2010 | 13/02/2010 | - (third row inserted) ERROR
第三行违反了唯一索引。因为28/01/2010
到13/02/2010
的时间间隔与01/01/2010
和01/02/2010
相交。
处理此问题的最有效方法是什么?
答案 0 :(得分:4)
看看我对这个问题的回答: Adding constraints using subquery from other table
基本思想是编写一个标识和计算坏行的查询。将该查询转换为物化视图,并添加一个检查约束,只要坏行的nr大于0,该约束就会失败。
对您的表的查询看起来像这样:
select count(*) as bad_rows
from stack_overflow_question a
join stack_overflow_question b using(ssn, irn)
where a.rowid < b.rowid
and ( a.begin_date between b.begin_date and nvl(b.end_date, a.begin_date)
or b.begin_date between a.begin_date and nvl(a.end_date, b.begin_date)
);