3

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

4

3 回答 3

5

不错的尝试,但根据 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 和更早的版本中,大多数人倾向于创建派生列(以及以编程方式使它们保持最新的负担)。

于 2009-05-08T03:25:27.970 回答
2

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

于 2009-05-07T23:17:13.043 回答
-2

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

于 2009-05-07T23:54:03.780 回答