Oracle уникальное ограничение и уникальный индекс, игнорирующий пространство - PullRequest
2 голосов
/ 10 июня 2019

Я использовал 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: можно индексировать только чистые функции

Как определить уникальный индекс, который игнорирует пробелы (пробелы, табуляция, ...)?

1 Ответ

3 голосов
/ 10 июня 2019

Кажется, причина, по которой вам было разрешено использовать REGEXP_REPLACE в индексе на основе функций в Oracle 11g, заключалась в том, что это была ошибка только в Oracle 11g и, вероятно, также в 12.1.Это исправлено начиная с Oracle 12.2, и, следовательно, оно не позволит вам создать индекс, который использует REGEXP_REPLACE напрямую.Причина в том, что это недетерминированная функция.

Аналогичная проблема существует и с ограничением CHECK и подробно обсуждалась в этой публикации .

В вашем случае прощеПодход с использованием 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...