Могу ли я иметь отложенный уникальный функциональный индекс в Oracle? - PullRequest
2 голосов
/ 08 мая 2009

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

Ответы [ 3 ]

5 голосов
/ 08 мая 2009

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

Следовательно, определение УНИКАЛЬНОГО ограничения может быть только именами столбцов и не может быть выражениями столбцов.

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

1 голос
/ 08 мая 2009

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

0 голосов
/ 08 мая 2009

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

...