Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Проблемы перекодировки из UTF8 / 12 сообщений из 12, страница 1 из 1
01.04.2009, 18:07
    #35906558
AlMoVi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
Добрый день! Темы, отвечающей на мой вопрос вроде не нашел...

Требуется из файла, хранящего xml, считать данные сначало в clob, а затем перевести в xmltype.

Делаю следующим образом:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
    FUNCTION fcl_clob (file_name IN VARCHAR2)
      RETURN xmltype
   IS
      fptr     UTL_FILE.file_type;
      buff     RAW ( 32767 );
      pos      PLS_INTEGER        :=  1 ;
      buffer   VARCHAR2 ( 32767 );
      res      CLOB               := EMPTY_CLOB;
      res_xml  xmltype;
      l_len    PLS_INTEGER;
   BEGIN
      fptr := UTL_FILE.fopen ('JPRS_TEMP', file_name, 'RB', 32767 );
      DBMS_LOB.createtemporary (res, TRUE);
      DBMS_LOB.OPEN (res, DBMS_LOB.lob_readwrite);

      LOOP
         UTL_FILE.get_raw (fptr, buff);
         l_len := UTL_RAW.LENGTH (buff);
         buffer :=
                 UTL_RAW.cast_to_varchar2 (buff);

         IF LENGTH (buffer) >  0 
         THEN
            DBMS_LOB.writeappend (res, LENGTH (buffer), buffer);
         END IF;
      END LOOP;
   EXCEPTION
      WHEN NO_DATA_FOUND
      THEN
         UTL_FILE.fclose (fptr);
         pp_debug.p_pushmsg('PP_FILE.fcl_clob.s1 ');
         res := convert (res,'UTF8','CL8MSWIN1251');
         pp_debug.p_pushmsg('PP_FILE.fcl_clob.s2 ');
         res_xml := xmltype(res);
         pp_debug.p_pushmsg('PP_FILE.fcl_clob.s3 ');
         pp_debug.p_pushmsg('PP_FILE.fcl_clob.s4 ');
         RETURN res_xml;
   END fcl_clob;

Проблема в том, что в файле есть русские символы, в результате получаю вместо них что-то такого плана:

Код: plaintext
<Author>Кулагин Д.М.</Author>

Код: plaintext
1.
NLS_CHARACTERSET = AL32UTF8
NLS_NCHAR_CHARACTERSET = AL16UTF16

Без
Код: plaintext
res := convert (res,'UTF8','CL8MSWIN1251'); 

ругается на невозможность парсинга в xml.

Заранее спасибо!
...
Рейтинг: 0 / 0
01.04.2009, 18:22
    #35906600
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
AlMoVi,

см на utl_raw.cast_to_varchar2
ну и когда convert-ом конвертите - внимательно параметры проставляйте
...
Рейтинг: 0 / 0
01.04.2009, 18:24
    #35906605
AlMoVi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
orawish,

прошу прощения за нубизм, но не могли бы Вы рассказать поподробнее?
...
Рейтинг: 0 / 0
01.04.2009, 18:32
    #35906621
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
AlMoViorawish,

прошу прощения за нубизм, но не могли бы Вы рассказать поподробнее?
с utl_raw.cast_to_varchar2 я промазал (просто не углядел, что он таки есть в вашем коде).

а convert - не понятно, почему конвертите в 'CL8MSWIN1251'
...
Рейтинг: 0 / 0
01.04.2009, 18:34
    #35906624
AlMoVi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
orawish,

а не подскажете, во что следует конвертить?
...
Рейтинг: 0 / 0
01.04.2009, 18:43
    #35906647
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
AlMoViorawish,

а не подскажете, во что следует конвертить?
доку посмотрите - второй параметр в convert - это куда конвертить ,
а третий (необязательный) откуда .

с ваших же слов - всё совсем не так..
...
Рейтинг: 0 / 0
01.04.2009, 19:24
    #35906714
AlMoVi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
orawish,

Т.е. для перекодировки из UTF8 в CL8MSWIN1251, конверт должен выглядеть следующим образом?


Код: plaintext
         res := convert (res,'CL8MSWIN1251');
?
...
Рейтинг: 0 / 0
01.04.2009, 19:34
    #35906731
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
AlMoViorawish,

Т.е. для перекодировки из UTF8 в CL8MSWIN1251, конверт должен выглядеть следующим образом?


Код: plaintext
         res := convert (res,'CL8MSWIN1251');
?

уже лучше.

ну а вот это -
Код: plaintext
1.
NLS_CHARACTERSET = [color=red]AL32UTF8[/color]
NLS_NCHAR_CHARACTERSET = AL16UTF16

зачем вы в первом посте писали ? ;)
...
Рейтинг: 0 / 0
02.04.2009, 10:09
    #35907391
AlMoVi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
orawish,

при конверте в AL32UTF8, парсинг xml ругается... этот вариант я пробовал(
...
Рейтинг: 0 / 0
02.04.2009, 12:23
    #35907953
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
AlMoVi,

поймите - всё же очень просто. надо лишь понимать, что у вас есть изначально и
что делает каждая процедура, которую вы используете для конвертации.
попробуем разжевать:
1) изначально у вас есть файл с данными, в кодировке utf8 (это вы говорите - на самом деле - не знаю в какой).
2) вы его прочитали в бинарном режиме и данные имеете, как raw
3) теперь их можно конвертировать в строковые (UTL_RAW.cast_to_varchar2 или ..nvarchar2)
вот здесь - место, где надо остановиться и подумать что же вы тут получили.
если исходная кодировка (данных в файле) совпадает с той, что на выходе 3)
(т.е. соотв. nls - настройке в базе) - то делать больше ничего и не надо, т.к. ваши данные
уже стали такими, как в базе.

отдельная песня, если вы затем хотите переформатировать данные из базы , но я
советую решать задачу последовательно. (а вдруг вы это просто зря придумали?)

ну дак из-за чего могут быть косяки - из за того, что начальная кодировка (в файле)
не совпадает с той, что на выходе 3) . тут оказывается, что бинарные байтики из
исходного файла в момент, когда стали строкой получили (по-позиции) значения символов использованной соотв. функцией базовой(nls) кодировки. Чтобы вернуть их на свое место - надо провести перекодировку, обратную той, которую неявно выполнило преобразование бинарных данных в строковые.

ну а по-простому:
1) прочитайте десяток (показательных) байт из файла
2) UTL_RAW.cast_to_varchar2 / UTL_RAW.cast_to_nvarchar2
3) посмотрите - что получили (dump или т.п.) -- сможете определить настоящую кодировку данных в файле
4) если надо , convert, после которого данные соответствуют кодировке в базе
5) и вот только тут - (за отдельное, если надо ) конверт в некую кодировку
отличную от базовой
...
Рейтинг: 0 / 0
03.04.2009, 09:06
    #35909778
Egwar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
Я использую такой метод
1) читаем все в байтах (в blob если надо данные хранить для истории)
2) определяем или подбираем кодировку (если не угадали - у нас данные исходные есть в Blob)
3) перекодируем в нужную кодировку с помощью нижеприведеных методов:
плюсы - можно использовать синонимы кодировок (UTF8,utf-8;windows-1251,cp1251,Cp1251) Не особо задумываясь, например открыли абы как xml - прочитали заголовок с указанием кодировки xml, и конвертнули в неё.


Делаем java-class c такими методами
public class Tools
{

//------------------------------------------------------------------------------
public static byte[] StringToByte(String pStr, String pEncode ) throws java.io.UnsupportedEncodingException
{
if (pEncode==null)
{
return pStr.getBytes();
}
else
{
return pStr.getBytes(pEncode);
}
}
//------------------------------------------------------------------------------
public static String ByteToString(byte[] pByte, String pEncode ) throws java.io.UnsupportedEncodingException
{
if (pEncode==null)
{
return new String(pByte);
}
else
{
return new String(pByte, pEncode);
}
}
}
Выводим эти методы в служебный PL/SQL пакедж для удобства использования:
...какой-то пакедж...
function CharToByte(pString varchar, pEncode varchar) return raw
is language java name 'Tools.StringToByte(java.lang.String, java.lang.String) return byte[]';
function ByteToChar(pHex raw, pEncode varchar) return varchar
is language java name 'Tools.ByteToString(byte[], java.lang.String) return java.lang.String';

P.S. Главное, помнить, что как только информация попадает в символьную переменную (varchar) - она там лежит в кодировке базы, т.е. информация уже безвозвратно (не всегда обратимо) сконвертирована.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
01.03.2018, 17:20
    #39609237
umalov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы перекодировки из UTF8
orawishAlMoVi,

поймите - всё же очень просто. надо лишь понимать, что у вас есть изначально и
что делает каждая процедура, которую вы используете для конвертации.
попробуем разжевать:
1) изначально у вас есть файл с данными, в кодировке utf8 (это вы говорите - на самом деле - не знаю в какой).
2) вы его прочитали в бинарном режиме и данные имеете, как raw
3) теперь их можно конвертировать в строковые (UTL_RAW.cast_to_varchar2 или ..nvarchar2)
вот здесь - место, где надо остановиться и подумать что же вы тут получили.
если исходная кодировка (данных в файле) совпадает с той, что на выходе 3)
(т.е. соотв. nls - настройке в базе) - то делать больше ничего и не надо, т.к. ваши данные
уже стали такими, как в базе.

...
Добрый день.
orawish - Спасибо большое за развёрнутый ответ.
Очень помогло в решении моей проблемы.
Запутался в кодировках, но после прочтения вашего сообщения , внимательно прошёлся по коду, следуя вашей инструкции - всё получилось.
Благодарю!
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Проблемы перекодировки из UTF8 / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]