2009-05-07 5 views
2

Я хотел бы создать отложенный уникальный функциональный индекс в Oracle 10g.Могу ли я иметь отложенный уникальный функциональный индекс в Oracle?

Я знаю, как создать уникальный функциональный индекс:

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 не поддерживает отложенные функциональные индексы? Может ли кто-нибудь предоставить мне решение или окончательный ответ?

ответ

5

Хорошая попытка, но в соответствии с 10г документации Oracle, синтаксис 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 ] 

Поэтому однозначное определение ограничение может быть только имена столбцов, и не может быть столбцов выражения.

Вы можете сделать это в 11g с использованием виртуальных столбцов, в 10g и более ранних случаях большинство людей склонны создавать производные столбцы (наряду с бременем поддержания их в актуальном состоянии программно).

+0

Ну, я попросил окончательного ответа, и, видимо, это все, даже если это не тот, на который я надеялся. ;) – Chris

1

Я думаю, вам нужна функциональность 11g virtual columns. Вы должны создать функцию как виртуальный столбец, а затем добавить cosntraint.

+0

У меня нет готового доступа к установке 11g. Может кто-то подтвердить решение Гэри? Я заметил это утверждение в ссылке на язык, приведенную выше: «Индекс таблицы, определенный в виртуальном столбце, эквивалентен индексу на основе функций в таблице». Если действительно есть решение с использованием 11 г виртуальных столбцов, то, возможно, есть эквивалентное решение без них? – Chris

-2

Ask Tom решает эту проблему. Ответ - нет, вы не можете создавать уникальные ограничения, основанные на функциональных индексах.

+0

Связанная статья «Спросите Том», по-видимому, касается только касательной к вопросу. Пользователь в статье задает вопрос о том, как создать «выборочно уникальный» индекс с novalidate, на который ответ в основном «Зачем использовать novalidate? Просто сделайте свой индекс еще более избирательным, чтобы получить то, что вы хотите». В ответе четко не указано, действительно ли возможно иметь функциональный индекс с NOVALIDATE, и даже не упоминает, что индекс откладывается. – Chris

+0

Вы четко * можете * создавать уникальные ограничения на основе функциональных индексов. Вопрос в том, как сделать их отложенными. – Chris

 Смежные вопросы

  • Нет связанных вопросов^_^