忽略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 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