![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ORA 9.2 BLOB->CLOB [D7]
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