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