我可以在Oracle中拥有一个可延迟的唯一功能索引吗?

我可以在Oracle中拥有一个可延迟的唯一功能索引吗?,oracle,indexing,unique,ora-00904,Oracle,Indexing,Unique,Ora 00904,我想在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); 我知道如何创建可延迟的唯一索引: alte

我想在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不支持可延迟函数索引?有人能为我提供一个解决方案或明确的答案吗?

我认为您需要11g功能。您可以将函数创建为虚拟列,然后在该列上添加共约束。

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

很好的尝试,但根据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 }
因此,CREATEINDEX允许列_表达式,它基本上是一个“基于函数的索引”

另一方面:

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 ]
因此,唯一约束定义只能是列名,不能是列表达式


您可以在11g中使用虚拟列来实现这一点,在10g和更早的版本中,大多数人倾向于创建派生列(以及通过编程使其保持最新状态的负担)。

我没有现成的11g安装访问权限。有人能证实加里的解决方案吗?我注意到上面链接的语言参考中有这样一句话:“在虚拟列上定义的表索引相当于在表上定义的基于函数的索引。”如果确实存在使用11g虚拟列的解决方案,那么可能存在没有它们的等效解决方案?链接的“Ask Tom”这篇文章似乎只和这里的问题有切身的联系。文章中的用户询问如何使用novalidate创建一个“选择性唯一”索引,对此的回答基本上是“为什么使用novalidate?只是让你的索引更具选择性,以获得你想要的。”回答没有明确指出是否真的可以使用novalidate创建功能索引,甚至没有提到使索引可延迟。显然,您可以基于函数索引创建唯一的约束。问题是如何让他们延期。好吧,我要求一个明确的答案,显然就是这样,即使这不是我所希望的