Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

ORA 9.2 BLOB->CLOB [D7]


Страницы:   1 2

GERDA ©   (2006-03-14 18:21:00) 

Как наиболее бысто
используя Utl_encode.base64_encode
перевести BLOB в CLOB


GERDA   (2006-03-15 18:10:00) [1]

А стиль вообще кривой -> не показали бы свой(поучиться).


Reindeer Moss Eater   (2006-03-15 17:58:00) [2]

Я отвечал без девелопера под рукой и под неправильной работой функции понял то, что само значение b64 получается разным.
То, что там вся разница в разном количестве #13#10 при разной длине блока я просто не допустил.

А стиль вообще кривой.
Стоит в следующем патче или версии Оракла изменить реализацию пакетов и все. С такими циклами приплыли.


GERDA   (2006-03-15 17:54:00) [3]

Беспокойства не было.
"Стандартом для b64 предусмотрены разделители #13#10"->
Вы как большой знаток могли бы и раньше об этом сказать.

И работает без явного выхода из цикла.


Reindeer Moss Eater   (2006-03-15 17:36:00) [4]

Ну а в чем собственно беспокойство-то?
Стандартом для b64 предусмотрены разделители #13#10.
Где их ставить не определено, только рекомендовано.


GERDA   (2006-03-15 17:32:00) [5]

Для Reindeer Moss Eater 
окончательный вариант - без явного выхода из цикла

function encodeBase64(aBlob blob) return clob
is
 CRLF       constant varchar2(2):=CHR(13)||CHR(10);
 aClob      clob;
 aRaw       RAW(32767);
 aVar       Varchar2(32767);        
 amount     number := 21000;
 offset     number default 1 ;
BEGIN
 dbms_lob.createtemporary(aClob,true);
 dbms_lob.open(aClob,DBMS_LOB.lob_readwrite);
 begin
     loop
       DBMS_LOB.READ(aBlob, amount, offset, aRaw);
        aRaw := utl_encode.base64_encode(aRaw);
        aVar:=replace(utl_raw.cast_to_varchar2(aRaw),CRLF);
       dbms_lob.WriteAppend(aClob, length(aVar),aVar);
       offset:=offset + amount;
       amount:=21000;        
    end loop;
 exception
   when others then null;
 end;
 return aClob;
end;


GERDA   (2006-03-15 13:37:00) [6]

В моем НЕ ДУРАЦКОМ цикле
выход осуществляется при
DBMS_LOB.READ(aBlob, amount, offset, aRaw);
Когда нет данных.

Покажите как надо.

еще раз см. ниже

declare
r0 raw(128):=utl_raw.cast_to_raw('123456789012123456789012123456789012123456789abc'  );
begin
  dbms_output.put_line(utl_raw.length(r0)); = 48
         
  r0:=utl_encode.base64_encode(r0);
  dbms_output.put_line(utl_raw.length(r0)); =66 а длжно быть 64 = 48 * 4 / 3

  dbms_output.put_line(r0);
  добавил в конец 0D0A    
end;


Reindeer Moss Eater   (2006-03-15 13:32:00) [7]

У тебя цикл есть?
Есть.
Он бесконечный?
Бесконечный.
Выход по условию есть?
Хрен!
Выходим из цикла как?
ТОЛЬКО ПО ВОЗНИКШЕМУ ИСКЛЮЧЕНИЮ ВЫХОДИМ!
Что в твоем дурацком цикле может вызвать исключение?
Где постобработка после выхода из твоего дурацкого цикла?


GERDA   (2006-03-15 13:28:00) [8]

Reindeer Moss Eater я в чудеса не верю и функция написана правильно поверь.

У меня
select * from v$version дает
Oracle9i Enterprise Edition Release 9.2.0.5.0 - Production

Далее

declare
r0 raw(128):=utl_raw.cast_to_raw('123456789012123456789012123456789012123456789abc' );
begin
   dbms_output.put_line(utl_raw.length(r0)); = 48
         
   r0:=utl_encode.base64_encode(r0);
   dbms_output.put_line(utl_raw.length(r0)); =66 а длжно быть 64 = 48 * 4 / 3

   dbms_output.put_line(r0);
   добавил в конец 0D0A    
end;

Так вот бывает.


Reindeer Moss Eater   (2006-03-15 13:03:00) [9]

Герда, ты в чудеса веришь?
Результат твоей функции зависит от длины блока на одних и тех же входных данных. Это ни о чем тебе не говорит?
У тебя цикл, в котором нет exit when,  и  из которого единственный выход - только по возникшему исключению.
И при этом ты продолжаешь упираться рогом.


GERDA   (2006-03-15 12:27:00) [10]

???


GERDA   (2006-03-15 12:14:00) [11]

Нет, не спасибо

См. function
1.Очереденое смещение улетает за границы блоба.
Этого быть не может
offset:=offset + amount; -- следующее смещение

Или не улетает, но требуется считать 21000 байтов.
на входу  amount = 21000
DBMS_LOB.READ(aBlob, amount, offset, aRaw);
на выходе ( в Вашем примере = 99)


GERDA   (2006-03-15 12:07:00) [12]

ДА.
СПАСИБО


Reindeer Moss Eater   (2006-03-15 12:05:00) [13]

Здорово.
Допустим, что до конца блоба еще 99 байтов.
Очереденое смещение улетает за границы блоба. Или не улетает, но требуется считать 21000 байтов.
Вылетаем по исключению.

А где наш непрочитанный хвостик из 99 байтов?


GERDA   (2006-03-15 12:01:00) [14]

1.Перед преобразованием в base64 не проверяется, был ли считан хотя бы   один байт.
 Выход по exception
2. offset:=offset + amount;
Выход по exception


Reindeer Moss Eater   (2006-03-15 11:34:00) [15]

после чтения дает реальный amount считанных данных

Дает.
Что бы программист проверял его.
Перед преобразованием в base64 не проверяется, был ли считан хотя бы один байт.

Еще не проверяется не превысит ли итоговый офсет длину блоба:
offset:=offset + amount;


GERDA   (2006-03-15 11:10:00) [16]

DBMS_LOB.READ(aBlob, amount, offset, aRaw);

после чтения дает реальный amount считанных данных


Reindeer Moss Eater   (2006-03-15 10:23:00) [17]

Ниже приведенная function при разныз AMOUNT дает разные результаты

Видимо потому, что после чтения DBMS_LOB.READ(aBlob, amount, offset, aRaw);
не учитывается реально считанный размер данных.


Reindeer Moss Eater   (2006-03-15 10:01:00) [18]

>в каком чарсете нужен результат?

>На выходе CLOB в закодированном Base64

А разве не понятно из вопроса?


GERDA   (2006-03-15 09:58:00) [19]

CLOB -> CL8MSWIN1251

Ниже приведенная function при разныз AMOUNT дает разные результаты
Как написать правильно

function EncodeBase64( aBlob blob) return clob
is
 aClob clob;
 aRaw RAW(32000);
 amount         number default 21000 ;
 offset         number default 1;
BEGIN
 dbms_lob.createtemporary(aClob,true);
 dbms_lob.open(aClob,DBMS_LOB.lob_readwrite);
 begin
   loop
       DBMS_LOB.READ(aBlob, amount, offset, aRaw);
       aRaw := utl_encode.base64_encode(aRaw);
       dbms_lob.WriteAppend(aClob, utl_raw.LENGTH(aRaw),utl_raw.cast_to_varchar2(aRaw));
       offset:=offset + amount;
       amount:=21000;  
   end loop;
 exception
   when others then null;
 end;
 return aClob;
end;


Desdechado   (2006-03-14 19:07:00) [20]

попробуй PACKAGE SYS.dbms_lob


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо