Oracle текст поиска с неанглийскими символами - PullRequest
5 голосов
/ 13 июля 2011

Наша база данных Oracle - UTF8. Мы храним адреса, которые должны быть доступны для поиска. Некоторые названия улиц содержат неанглийские символы (например, Peña Báináõ), для которых необходимо выполнять поиск как « Peña Báináõ » или с английскими эквивалентными символами, такими как « Pena Bainao ». То, что мы сделали, это преобразовали текст в запросе, что-то вроде:

SELECT CONVERT('Peña Báináõ','US7ASCII') as converted FROM dual;

Но проблема здесь в том, что не все символы имеют английский эквивалент (даже не такие довольно очевидные, как ñ или õ), поэтому мы получаем текст, преобразованный в:

Pe?a Baina?

То есть, если пользователь пытается найти адрес, набрав " Pena Bainao ", он не может его найти, потому что " Pena Bainao " отличается от "" Pe? баина?"".

Мы нашли некоторые грязные способы решения этой проблемы, но сначала я хотел проверить, нашел ли кто-то более изящное решение.

Вот список некоторых символов, которые не преобразованы в US7ASCII:

Character     UTF8 Code     Possible Equivalent   
æ         -   u00E6      -      ae
å         -   u00E5      -       a
ã         -   u00E3      -       a
ñ         -   u00F1      -       n
õ         -   u00F5      -       o

1 Ответ

5 голосов
/ 13 июля 2011

1) Использование nlssort с BINARY_AI (регистр и акцент не учитываются):

SQL> select nlssort('Peña Báináõ', 'NLS_SORT = BINARY_AI') C from dual;

C
------------------------
70656E61206261696E616F00

SQL> select nlssort('Pena Bainao', 'NLS_SORT = BINARY_AI') C from dual;

C
------------------------
70656E61206261696E616F00

SQL> select nlssort('pena bainao', 'NLS_SORT = BINARY_AI') C from dual;

C
------------------------
70656E61206261696E616F00

SQL> select 'true' T from dual where nlssort('pena bainao', 'NLS_SORT = BINARY_AI') = nlssort('Peña Báináõ', 'NLS_SORT = BINARY_AI') ;

T
----
true

2) Вы также можете изменить переменную сеанса NLS_SORT на binary_ai, и тогда вам не придется каждый раз указывать NLS_SORT:

SQL> select 'true' T from dual where nlssort('pena bainao') = nlssort('Peña Báináõ') ;

no rows selected

SQL> alter session set nls_sort = binary_ai;

Session altered.

SQL> select 'true' T from dual where nlssort('pena bainao') = nlssort('Peña Báináõ') ;

T
----
true

3) Чтобы отказаться от использования функции nlssort и изменить семантику всего, также установите переменную сеанса nls_comp:

SQL> select 'true' T from dual where 'pena bainao' = 'Peña Báináõ';

no rows selected

SQL> alter session set nls_comp = linguistic;

Session altered.

SQL> select 'true' T from dual where 'pena bainao' = 'Peña Báináõ';

T
----
true

Вариант 1 изменяет только локальное поведение, запрос, в котором вы хотите разные результаты. Варианты 2 и 3 изменят поведение других запросов и могут не соответствовать вашим ожиданиям. См. Таблица 5-2 из Руководство по поддержке глобализации баз данных Oracle® . Также посмотрите раздел " Использование лингвистических индексов ", чтобы увидеть, как можно использовать индексы.

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