表检查约束以验证特定值的唯一性

AMG*_*AMG 0 oracle ddl check-constraints

Oracle 10g:假设有下表(T_REGISTER):

ID_PROCESS   PERIOD    CUSTOMER    STATUS
===========================================
0001234      201801    12300344    INVALID
0001236      201801    12300344    INVALID
0001246      201801    12300344    UNPAID
0001249      201801    12300344    UNPAID
0001278      201801    12300344    COMPLETED
Run Code Online (Sandbox Code Playgroud)

ID_PROCESS 是 PK。但我也需要 (PERIOD + CUSTOMER + STATUS) 在 STATUS 完成时是唯一的。

换句话说,对于一个 UNIQUE (PERIOD + CUSTOMER),我不在乎有几个 INVALID 或 UNPAID 行,但我只能承认一个唯一的 (PERIOD;CUSTOMER;STATUS="COMPLETED")

在寻求触发解决方案之前,有没有使用 CHECK CONSTRAINT 的优雅解决方案?提前致谢...

a1e*_*x07 5

检查约束不是为了强制唯一性。基于唯一函数的索引可以完成这项工作(因为 Oracle 接受唯一列上的多个 NULL 值)。

create table test1(ID_PROCESS   int , PERIOD int, CUSTOMER    int, STATUS varchar2(20));


create unique index idxu1_test1 on test1
    (case when STATUS ='COMPLETED' then PERIOD else null end,   
     case when STATUS ='COMPLETED' then CUSTOMER else null end 
     );


insert into test1(ID_PROCESS   ,PERIOD, CUSTOMER    , STATUS )
values (1,1,1, 'invalid'); -- ok
insert into test1(ID_PROCESS   ,PERIOD, CUSTOMER    , STATUS )
values (2,1,1, 'invalid'); -- ok
insert into test1(ID_PROCESS   ,PERIOD, CUSTOMER    , STATUS )
values (3,1,1, 'invalid'); -- ok


insert into test1(ID_PROCESS   ,PERIOD, CUSTOMER    , STATUS )
values (4,1,1, 'COMPLETED'); -- ok
insert into test1(ID_PROCESS   ,PERIOD, CUSTOMER    , STATUS )
values (5,1,1, 'COMPLETED'); -- ORA-00001: unique constraint violated 
Run Code Online (Sandbox Code Playgroud)