忽略space的Oracle唯一约束和唯一索引

Oracle unique constraint and unique index which ignoreing space

我使用了 Oracle 11g 和一些表,使用下面的命令在忽略所有白色的特定列上创建唯一索引 space。

CREATE UNIQUE INDEX UK_LOCATION_NAME ON LOCATION(UPPER(REGEXP_REPLACE("FARSI_NAME",'\s+','')));

最近Oracle数据库更新到12c,执行上述命令报错:

[2019-06-08 19:44:08] [42000][1743] ORA-01743: only pure functions can be indexed

如何定义忽略白色的唯一索引 spaces(spaces, tab, ...)?

您被允许在 Oracle 11g 中基于函数的索引中使用 REGEXP_REPLACE 的原因似乎是它仅在 Oracle 11g 中存在,并且可能在 12.1 中也是如此。它自 Oracle 12.2 以来已得到修复,因此它不允许您创建直接使用 REGEXP_REPLACE 的索引。原因是它是一个 Non-deterministic 函数。

CHECK 约束也存在类似的问题,并且已在 this post 上进行了详细讨论。

在你的情况下,如果你只是替换空格,使用 REPLACE 的更简单的方法应该就足够了。

CREATE UNIQUE INDEX UK_LOCATION_NAME 
     ON LOCATION(UPPER(replace("FARSI_NAME",' ')));

当您的替换模式很复杂时,解决此问题的另一种方法是使用替代函数 DETERMINISTIC。这是一种解决方法,对于复杂的场景可能效率不高。

create or replace function my_regex_rep(txt_in VARCHAR2) 
return VARCHAR2 DETERMINISTIC IS
 BEGIN
   return regexp_replace(txt_in,'\s+','');
 END;
 /

现在,您可以在 INDEX.

中使用此功能
CREATE UNIQUE INDEX UK_LOCATION_NAME ON 
     LOCATION(UPPER(my_regex_rep("FARSI_NAME")));

测试

INSERT INTO LOCATION(FARSI_NAME) values('ABCD EFGH');
1 row inserted.

INSERT INTO LOCATION(FARSI_NAME) values('   ABCD      efgh  ');
                                              --spaces
ORA-00001: unique constraint (HR.UK_LOCATION_NAME) violated

INSERT INTO LOCATION(FARSI_NAME) values('ABCD   EFGh');
                                           --tab

ORA-00001: unique constraint (HR.UK_LOCATION_NAME) violated

Oracle 18c DEMO