reverse + уникодица = кусок прикола

orawish
Дата: 30.05.2006 17:45:44
SQL> select reverse('АБВГДЕ') from dual;
ERROR:
ORA-29275: неполный многобайтовый символ
Это скуэльплюс.
Через OCI - результат выудить можно. Там
автор
ユДГВБАÐ

Т.е. крайний байтик порвали напополам и половину засунули взад, половину вперед. Еще видел - (на чужом 9.2.0.6 - на моих зверушках не повторилось) что length(reverse..) при этом подрастает на +1.

Так вот,вроде, работает..
select convert(reverse(convert('АБВГДЕ','CL8MSWIN1251',v)),v,'CL8MSWIN1251')
from (select value v from nls_database_parameters where parameter= 'NLS_CHARACTERSET');
Но осадок - остался
Elic
Дата: 30.05.2006 17:53:18
orawish
Дата: 30.05.2006 18:00:08
Elic
STFF Как "перевернуть" текст

Вот в том-то и прикол, что не просто \'побайтово переворачивает\'
Elic
Дата: 30.05.2006 18:24:32
orawish
Вот в том-то и прикол, что не просто 'побайтово переворачивает'
Где прикол?!!
with t as (select convert('АБВГДЕ','al16utf16') as s from dual)
select dump(s), dump(reverse(s)) from t
;

DUMP(S)                                       DUMP(REVERSE(S))
--------------------------------------------- -------------------------------------------
Typ=1 Len=12: 4,16,4,17,4,18,4,19,4,20,4,21 Typ=1 Len=12: 21,4,20,4,19,4,18,4,17,4,16,4
orawish
Дата: 30.05.2006 19:16:45
Согласен. Еще раз убедил - dump - полезная штука..
Через недельку, наверное, буду возле той базы - так и посмотрю, где
там длина прирастает..
Elic
Дата: 30.05.2006 19:36:28
orawish
посмотрю, где там длина прирастает..
Зачем?! Чего ты ждёшь от попытки произвольную "мусорную" последовательность байт привести к UTF?
orawish
Дата: 31.05.2006 12:01:48
Elic
orawish
посмотрю, где там длина прирастает..
Зачем?! Чего ты ждёшь от попытки произвольную "мусорную" последовательность байт привести к UTF?
Пользы практической, конечно, не жду никакой..
Тут все ясно - reverse имеет смысл применять только к однобайтовой строке (и то - с опаской:)
Но некоторых вещей, ну, не понимаю. Например, почему работает

SQL> select length(a),length(reverse(a)) from
  2  (select 'АБВ' a from dual);

 LENGTH(A) LENGTH(REVERSE(A))
---------- ------------------
         3                  3

тогда,как

SQL> select a,reverse(a) from
  2  (select 'АБВ' a from dual);
ERROR:
ORA-29275: неполный многобайтовый символ
Elic
Дата: 31.05.2006 12:21:12
orawish
Но некоторых вещей, ну, не понимаю. Например, почему работает
length(reverse(a))
"Кривая" строка не покидает сервера.
orawish
тогда,как
reverse(a)
ORA-29275: неполный многобайтовый символ
"Кривая" строка передаётся клиенту и по дороге попадает в NLS-кухню. О чём, собственно, и говорится в описании ошибки.
Goldminer
Дата: 31.05.2006 14:37:15
Как я понял, reverse() как раз работает правильно (т.е. как задумано), а вот некорректность поведения "NLS кухни" налицо - в смысле - incompliat сточки зрения Unicode. Там расписаны варианты поведения при встрече с незнакомым символом - программа не должна считать, что ей известны все мировые алфавиты. А уж терять синхронизацию - это ни в какие ворота. А именно это и происходит. В UTF16 символ начинается с четной границы - закон природы - и никаких "неполных" быть не может (кол-во байтов не меняется). А он, значит видит старший байт 21, понимает, что такой диапазон ему незнаком (не поленился, заглянул - письменность канадских аборигенов там находится - серьезно ;-))))) и переходит ко ВТОРОМУ! Что и порождает указанный "обман зрения", дескать reverse() работает "почти правильно", только
orawish

крайний байтик порвали напополам и половину засунули взад, половину вперед.

А если, скажем, кириллицу с латиницей перемешать - перестает. Ну чем не прикол? :-)))
Elic
Дата: 31.05.2006 14:55:02
Goldminer
Как я понял, reverse() как раз работает правильно (т.е. как задумано)
Не нам судить: правильно/неправильно, задумано/нет - она недокументирована. Её использование - личные сексуальные проблемы отдельно взятого индивидуума :)
Goldminer
А если, скажем, кириллицу с латиницей перемешать - перестает. Ну чем не прикол? :-)))
Ещё раз: нет никакого прикола. Любой вывод, основанный на ложной посылке (кривой строке), тоже будет ложным. Даже тот, который тебе кажется правильным