【问题标题】:Can I have a deferrable unique functional index in Oracle?我可以在 Oracle 中有一个可延迟的唯一功能索引吗?
【发布时间】:2009-05-07 22:10:04
【问题描述】:

我想在 Oracle 10g 中创建一个可延迟的唯一功能索引。

我知道如何创建唯一的函数索引:

create unique index LIST_ITEM_ENTRY_NO_UNIQ
on LIST_ITEM (case status when 'cancel' then null else LIST_KEY end,
              case status when 'cancel' then null else ENTRY_NO end);

我知道如何创建可延迟的唯一索引:

alter table LIST_ITEM add constraint LIST_ITEM_ENTRY_NO_UNIQ
unique (LIST_KEY,ENTRY_NO) deferrable initially deferred;

知道这两件事,我尝试了这个:

alter table LIST_ITEM add constraint LIST_ITEM_ENTRY_NO_UNIQ
unique (case STATUS when 'cancel' then null else LIST_KEY end,
        case STATUS when 'cancel' then null else ENTRY_NO end)
deferrable initially deferred;

但我收到“ORA-00904:无效标识符”错误。要么我的语法错误,要么 Oracle 不支持可延迟的功能索引?有人可以为我提供解决方案或明确的答案吗?

【问题讨论】:

    标签: oracle indexing unique ora-00904


    【解决方案1】:

    不错的尝试,但根据 Oracle 10g 文档,在这方面 CREATE INDEX 和 ALTER TABLE ADD CONSTRAINT 的语法不可互换,这就是您收到语法错误的原因:

    CREATE INDEX ::=
    
        CREATE [ UNIQUE | BITMAP ] INDEX [ schema. ]index
          ON { cluster_index_clause
             | table_index_clause
             | bitmap_join_index_clause
             } ;
    
    table_index_clause ::=
    
        [ schema. ]table [ t_alias ]
        (index_expr [ ASC | DESC ]
          [, index_expr [ ASC | DESC ] ]...)
        [ index_properties ]
    
    index_expr ::= { column | column_expression }
    

    因此 CREATE INDEX 允许 column_expression,它基本上是一个“基于函数的索引”。

    另一方面:

    ALTER TABLE ::=
    ALTER TABLE [ schema. ]table
      [ alter_table_properties
      | column_clauses
      | constraint_clauses
      | alter_table_partitioning
      | alter_external_table_clauses
      | move_table_clause
      ]
      [ enable_disable_clause
      | { ENABLE | DISABLE }
        { TABLE LOCK | ALL TRIGGERS }
        [ enable_disable_clause
        | { ENABLE | DISABLE }
          { TABLE LOCK | ALL TRIGGERS }
        ]...
      ] ;
    
    constraint_clauses ::=
    { ADD { out_of_line_constraint
            [ out_of_line_constraint ]...
          | out_of_line_REF_constraint
          }
    | MODIFY { CONSTRAINT constraint
             | PRIMARY KEY
             | UNIQUE (column [, column ]...)
             }
             constraint_state
    | RENAME CONSTRAINT old_name TO new_name
    | drop_constraint_clause
    }
    
    out_of_line_constraint ::=
    [ CONSTRAINT constraint_name ]
    { UNIQUE (column [, column ]...)
    | PRIMARY KEY (column [, column ]...)
    | FOREIGN KEY (column [, column ]...)
         references_clause
    | CHECK (condition)
    }
    [ constraint_state ]
    

    因此,UNIQUE 约束定义只能是列名,不能是列表达式。

    您可以在 11g 中使用虚拟列来做到这一点,在 10g 和更早的版本中,大多数人倾向于创建派生列(以及以编程方式使它们保持最新的负担)。

    【讨论】:

    • 嗯,我要求一个明确的答案,显然就是这样,即使它不是我所希望的。 ;)
    【解决方案2】:

    我认为您需要 11g virtual columns 功能。您可以将函数创建为虚拟列,然后在其上添加 cosntraint。

    【讨论】:

    • 我无法访问 11g 安装。有人可以确认加里的解决方案吗?我注意到上面链接的语言参考中的这条语句:“在虚拟列上定义的表索引等同于表上基于函数的索引。”如果确实有使用 11g 虚拟列的解决方案,那么也许没有它们的等效解决方案?
    【解决方案3】:

    Ask Tom 解决了这个问题。答案是否定的,您不能基于功能索引创建唯一约束。

    【讨论】:

    • 链接的“Ask Tom”文章似乎与此处的问题无关。文章中的用户询问如何使用 novalidate 创建一个“选择性唯一”索引,对此的回答基本上是“为什么使用 novalidate?只需让您的索引更具选择性以获得您想要的内容。”响应没有明确指出是否真的可以使用 NOVALIDATE 建立功能性索引,甚至没有提到使索引可延迟。
    • 您显然可以根据功能索引创建唯一约束。问题是如何使它们可延期。
    猜你喜欢
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    相关资源
    最近更新 更多