由于您使用的是 Oracle 18,因此您可以使用不可见列和虚拟列等新功能或collation:
虚拟不可见列+唯一约束:
例如,您有一个包含 STR 列的表 T:
create table t(str varchar2(10));
所以你可以添加不可见的虚拟列str_lower 生成为lower(str):
alter table t add
str_lower varchar2(10) invisible generated always as (lower(str)) ;
由于此列是不可见且虚拟的,因此不会破坏您现有的代码。
现在您可以在其上添加unique 约束:
alter table t add
constraint t_str_unique_lower
unique(str_lower) using index;
测试它:
SQL> insert into t values('M100');
1 row created.
SQL> insert into t values('m100');
insert into t values('m100')
*
ERROR at line 1:
ORA-00001: unique constraint (XTENDER.T_STR_UNIQUE_LOWER) violated
此外,它还允许您通过较低的值轻松找到值:
SQL> select * from t where str_lower='m100';
STR
----------
M100
SQL> select str,str_lower from t where str_lower='m100';
STR STR_LOWER
---------- ----------
M100 m100
如您所见,如果您未在选择列表中指定它,它不会返回 str_lower 列:
另一种可能的解决方案是为您的列指定collation,但需要将数据库参数MAX_STRING_SIZE 设置为EXTENDED,否则您将得到ORA-43929: Collation cannot be specified if parameter MAX_STRING_SIZE=STANDARD is set.
alter table t modify str COLLATE BINARY_CI;
alter table t add constraint t_str_unique unique(str);
更多信息:
https://oracle-base.com/articles/12c/column-level-collation-and-case-insensitive-database-12cr2