我已经使用了Oracle 11g,并且对某些表使用了以下命令,以便在特定列上创建一个唯一索引,该索引将忽略所有空白。
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:只能对纯函数进行索引
如何定义一个忽略空格(空格,制表符,...)的唯一索引?
答案 0 :(得分:3)
在Oracle 11g中基于功能的索引中被允许使用REGEXP_REPLACE
的原因似乎是,它仅在Oracle 11g中以及在12.1中才是错误。自Oracle 12.2起,此问题已得到修复,因此不允许您创建直接使用REGEXP_REPLACE
的索引。原因是它是不确定性函数。
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