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

发布于 2024-07-19 07:50:26 字数 804 浏览 6 评论 0原文

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

I'd like to create a deferrable unique functional index in Oracle 10g.

I know how to create a unique functional index:

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);

I know how to create a deferrable unique index:

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

Knowing these two things, I tried this:

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;

But I get an "ORA-00904 : invalid identifier" error. Either I've got the syntax wrong, or perhaps Oracle doesn't support deferrable functional indices? Could someone provide me with a solution or else a definitive answer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寂寞清仓 2024-07-26 07:50:26

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

Nice try, but according to the Oracle 10g Documentation, the syntax for CREATE INDEX and ALTER TABLE ADD CONSTRAINT are not interchangeable in this regard, which is why you got that syntax error:

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 }

Therefore CREATE INDEX allows column_expression, which is basically a "function-based index".

On the other hand:

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 ]

Therefore a UNIQUE constraint definition may only be column names, and cannot be column expressions.

You can do this in 11g using virtual columns, in 10g and earlier most people tend to create derived columns (along with the burden of keeping them up-to-date programmatically).

满栀 2024-07-26 07:50:26

I think you need the 11g virtual columns functionality. You'd create the function as a virtual column, then add the cosntraint on that.

风轻花落早 2024-07-26 07:50:26

询问 Tom 地址这个问题。 答案是否定的,您不能根据功能索引创建唯一约束。

Ask Tom addresses this issue. The answer is no, you can't create unique constraints based upon functional indexes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文