【问题标题】:conditional unique constraint on multiple columns in oracleoracle中多列的条件唯一约束
【发布时间】:2019-11-02 03:52:51
【问题描述】:

我有一个包含三列的表 - c_id、o_id、f_id。只要 f_id 不为 3,三个 id 的组合就必须是唯一的。

在阅读了类似的问题后,我尝试了以下方法:

create unique index my_index on my_table (
decode (f_id, !3, c_id, null),
decode (f_id, !3, o_id, null),
decode (f_id, !3, f_id, null));

但我得到一个 missing expression 错误。我也试过

create unique index my_index on my_table ((
case 
when f_id <> 3 then c_id
when f_id <> 3 then o_id
when f_id <> 3 then f_id
else null
end));

但是对于这个我得到无法创建索引;发现重复键

原来我试过

when f_id <> 3 then (c_id, o_id, f_id)

但这根本不起作用。

无论如何,索引可能有问题,因为表似乎没有任何重复项,我没有得到任何记录

select c_id, o_id, f_id, count(*) as dupes
from my_table
where f_id <> 3
having count(*) > 1
group by c_id, o_id, f_id;

我对这些 FBI 有点盲目,因此我们将不胜感激。

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    您似乎想要一个 3 部分索引:

    create unique index my_index
        on my_table (case when f_id <> 3 then c_id end,
                     case when f_id <> 3 then o_id end,
                     case when f_id <> 3 then f_id end
                    );
    

    【讨论】:

    • 这行得通。但是,当f_id 为空时,它也允许(c_id,o_id) 的重复组合(这与复合唯一键的正常行为方式不同)。
    • 它似乎正在工作。一旦我做更多的测试,我会接受它。你能解释一下三部分索引和我使用的不正确的情况有什么区别吗?
    • @tom - 您的 CASE 解决方案版本仅索引单个列,因为它有一个 CASE 语句。这就是为什么你会得到重复值异常。 Gordon 的解决方案有三个 CASE 语句,每个要索引的列一个,
    【解决方案2】:

    只有一个列索引的替代方法:

    create unique index all_but_3 on tst (case when nvl(f_id,0) != 3 then o_id||'.'||c_id||'.'||f_id end);
    

    测试

    insert into tst(c_id, o_id, f_id) values(3,3,3);
    insert into tst(c_id, o_id, f_id) values(3,3,3); -- OK
    
    insert into tst(c_id, o_id, f_id) values(3,3,2);
    insert into tst(c_id, o_id, f_id) values(3,3,2); -- ORA-00001: unique constraint  xxx violated
    
    insert into tst(c_id, o_id, f_id) values(3,3,null);
    insert into tst(c_id, o_id, f_id) values(3,3,null); -- ORA-00001: unique constraint  xxx violated
    
    insert into tst(c_id, o_id, f_id) values(null,null,2);
    insert into tst(c_id, o_id, f_id) values(null,null,2); -- -- ORA-00001: unique constraint  xxx violated
    

    【讨论】:

      猜你喜欢
      • 2012-07-21
      • 1970-01-01
      • 2012-05-06
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      • 2012-08-10
      相关资源
      最近更新 更多