2008-10-27 2 views
1

Я хотел бы использовать функцию utl_match.edit_distance Oracle. Он должен сравнить две строки и вернуть Levenshtein distance.Oracle utl_match специальные символы

select utl_match.edit_distance('a','b') from dual 

возвращает 1, как и ожидалось, но

select utl_match.edit_distance('á','b') from dual 

возвращается 2. Очевидно, что я хотел бы получить 1.

Казалось бы, он не работает правильно для специальных символов. Я использую набор символов Oracle 10.2.0.4 и AL32UTF8.

ответ

2

Это похоже на набор символов. Если я запускаю тот же тест в базе данных 10.2.0.3 и 11.1.0.7, используя ISO8859P15 в качестве набора символов, я также получаю расстояние 1. Я предполагаю, что Oracle вычисляет расстояние в терминах байтов, а не символов в наборах символов переменной ширины.

Вы можете обойти эту проблему с помощью функции CONVERT для преобразования фиксированной ширины набора символов (AL16UTF16 или локальный набор символов)

SQL> ed 
Wrote file afiedt.buf 

    1 declare 
    2 l_char1 varchar2(1 char) := 'á'; 
    3 l_char2 varchar2(1 char) := 'b'; 
    4 begin 
    5 dbms_output.put_line(
    6  'In AL32UTF8: ' || 
    7  utl_match.edit_distance(l_char1, l_char2)); 
    8 dbms_output.put_line(
    9  'In WE8ISO8859P15: ' || 
10  utl_match.edit_distance(
11   CONVERT(l_char1, 'WE8ISO8859P15', 'AL32UTF8'), 
12   CONVERT(l_char2, 'WE8ISO8859P15', 'AL32UTF8'))); 
13 dbms_output.put_line(
14  'In AL16UTF16: ' || 
15  utl_match.edit_distance(
16   CONVERT(l_char1, 'AL16UTF16', 'AL32UTF8'), 
17   CONVERT(l_char2, 'AL16UTF16', 'AL32UTF8'))); 
18* end; 
SQL>/
In AL32UTF8: 2 
In WE8ISO8859P15: 1 
In AL16UTF16: 1 

PL/SQL procedure successfully completed. 
+0

Спасибо за обходной путь. Весьма странно, но сравнение «a» с «bb» дает 2 в AL32UTF8, 2 в WE8ISO8859P15, но 3 в AL16UTF16. – asalamon74 2008-10-28 09:45:07

1

Согласен, что это неправильно. Однако этот пакет недокументирован Oracle, поэтому, возможно, он не поддерживается в настоящее время.

Смежные вопросы