【问题标题】:Oracle: function based index selective uniquenessOracle:基于函数的索引选择性唯一性
【发布时间】:2011-10-05 20:28:00
【问题描述】:

我必须维护历史记录,所以我使用的是 is_deleted 列,它可以有“Y”或“N”。但是对于 is_deleted 'N' 的任何实例,我都应该有 (a,b,c) 复合列的 uniwue 条目。

当我尝试创建基于函数的唯一索引时出现错误。

CREATE UNIQUE INDEX fn_unique_idx ON table1  (CASE WHEN is_deleted='N' then (id, name, type) end);

第 1 行的错误: ORA-00907: 缺少右括号

请帮忙。

谢谢

【问题讨论】:

    标签: sql oracle indexing


    【解决方案1】:

    你需要类似的东西

    CREATE UNIQUE INDEX fn_unique_idx 
        ON table1 (CASE WHEN is_deleted='N' THEN id ELSE null END,
                   CASE WHEN is_deleted='N' THEN name ELSE null END,
                   CASE WHEN is_deleted='N' THEN type ELSE null END);
    

    约束实例

    SQL> create table table1 (
      2    id number,
      3    name varchar2(10),
      4    type varchar2(10),
      5    is_deleted varchar2(1)
      6  );
    
    Table created.
    
    SQL> CREATE UNIQUE INDEX fn_unique_idx
      2      ON table1 (CASE WHEN is_deleted='N' THEN id ELSE null END,
      3                 CASE WHEN is_deleted='N' THEN name ELSE null END,
      4                 CASE WHEN is_deleted='N' THEN type ELSE null END);
    
    Index created.
    
    SQL> insert into table1 values( 1, 'Foo', 'Bar', 'N' );
    
    1 row created.
    
    SQL> insert into table1 values( 1, 'Foo', 'Bar', 'Y' );
    
    1 row created.
    
    SQL> insert into table1 values( 1, 'Foo', 'Bar', 'Y' );
    
    1 row created.
    
    SQL> insert into table1 values( 1, 'Foo', 'Bar', 'N' );
    insert into table1 values( 1, 'Foo', 'Bar', 'N' )
    *
    ERROR at line 1:
    ORA-00001: unique constraint (SCOTT.FN_UNIQUE_IDX) violated
    
    
    SQL> insert into table1 values( 1, 'Foo', 'Zee', 'N' );
    
    1 row created.
    

    【讨论】:

    • 但我的用例是当 is_deleted = 'N' 然后组合 (id,name,type) - 复合键应该是唯一的。您的查询会达到同样的效果吗?
    • @Andriod_therapy - 确实如此。我用我运行的测试更新了我的答案。
    • 非常感谢。欣赏它。因此,如果我对这些列没有空约束,我想我可以省略 ELSE null
    • 不,您需要将 is_deleted 为 'Y' 的行中的数据映射为 NULL,以便将它们从索引中排除。你需要 ELSE 条件
    • 其实ELSE部分是多余的。如果没有 ELSE 部分,CASE 默认返回 NULL。把它拼出来只是一个好习惯,它与在单个列上具有 NOT NULL 约束无关。
    【解决方案2】:
    CREATE UNIQUE INDEX fn_unique_idx ON table1  
        (CASE WHEN is_deleted='N' then (id||','|| name||','|| type) end);
    

    【讨论】:

      猜你喜欢
      • 2011-10-09
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 2014-04-11
      • 1970-01-01
      • 2013-09-26
      • 2013-03-02
      • 1970-01-01
      相关资源
      最近更新 更多