У меня есть xml-файл размером около 3,5 МБ. Я поддерживаю его и распространяю на другую базу данных, где мне нужно ее расшифровать. Я расшифровываю его в итерациях, так как он слишком велик, чтобы декодировать за один раз, однако в некоторых итерациях он не может декодироваться, я получаю некоторый giberish. Я считаю, что это потому, что некоторые символы могут быть 1 байт, а другие 2 байта, а иногда подстрока разрезает один символ из 2 байтов пополам и что итерация появится в виде. Я понял, что могу попытаться преобразовать каждую подстроку в clob, так как у нее есть предупреждения, когда она не может преобразовать символы, а если появляется предупреждение, увеличьте количество в подстроке на некоторое число, byt я еще не успел декодировать это путь. Есть ли обходной путь для этого?Декодирование больших base64 закодированных blobs
UPDATE
Преемник в расшифровке, с предупреждениями проверок. Все, что вам нужно сделать, это попытаться преобразовать подстроку в clob с dbms_lob.convertblobtoclob
проверить на warning != 0
, и если это уменьшит смещение на 1 и перейдите к следующей итерации, не приложив подстроку к вашему блобу. Однако это очень запоминающаяся дорогая проверка, потому что для этого требуется создать blob и трансформировать этот blob в clob. Есть ли более упрощенный обходной путь к этому, может быть, я пропущу что-то очень очевидное?
UPDATE
Я файл XML, который содержит платежное XML в кодировке base64, а также другие данные о том XML. F.E.
<envelope>
<file_name>a.xml</file_name>
<...><...>
<data>BASE64 ENCODED XML FILE</data>
</envelope>
Полный сценарий с несколькими примерами. Раньше я упомянул обходной путь с проверкой предупреждений, но в этом примере это, похоже, не работает, и когда я лучше думаю об этом, он не должен. Во всяком случае, вот скрипт:
declare
l_clob clob := empty_clob();
function convert_clob_to_blob(
p_clob in clob) return blob is
l_dest_offsset number := 1;
l_src_offsset number := 1;
l_lang_context number := dbms_lob.default_lang_ctx;
l_warning number;
l_result blob;
begin
dbms_lob.createtemporary(l_result, false);
dbms_lob.convertToBlob(
dest_lob => l_result,
src_clob => p_clob,
amount => dbms_lob.lobmaxsize,
dest_offset => l_dest_offsset,
src_offset => l_src_offsset,
blob_csid => dbms_lob.default_csid,
lang_context => l_lang_context,
warning => l_warning);
if l_warning != 0 then
raise_application_error(-20001, 'sd' || '.convert_blob_to_clob ' || l_warning);
end if;
return l_result;
end;
function gen_rand_xml return clob is
l_xml xmltype := xmltype('<envelope><nullnode></nullnode></envelope>');
begin
for i in 1..50 loop
SELECT
insertXMLafter(
l_xml,
'/envelope/nullnode',
XMLType('<node>' || i || '</node>'))
INTO
l_xml
FROM dual;
end loop;
return l_xml.getClobVal();
end;
function to_base64(
p_clob in clob) return clob is
l_length integer;
l_offset integer := 1;
l_amt binary_integer := 600;
l_buffer varchar2(1800);
l_result clob := empty_clob();
l_temp_blob blob;
begin
dbms_lob.createtemporary(l_temp_blob, false);
l_temp_blob := convert_clob_to_blob(p_clob);
l_length := dbms_lob.getlength(l_temp_blob);
while l_offset < l_length loop
l_result := l_result || utl_raw.cast_to_varchar2(utl_encode.base64_encode(dbms_lob.substr(l_temp_blob, l_amt, l_offset)));
l_offset := l_offset + l_amt;
end loop;
return l_result;
end;
function from_base64(
p_clob in clob) return clob is
l_length integer := dbms_lob.getLength(p_clob);
l_offset integer := 1;
l_amt binary_integer := 800;
l_buffer varchar2(3200);
l_result clob := empty_clob();
begin
while l_offset <= l_length loop
l_buffer := replace(replace(dbms_lob.substr(p_clob, l_amt, l_offset), chr(10), null), chr(13), null);
l_offset := l_offset + l_amt;
while l_offset <= l_length and mod(dbms_lob.getLength(l_buffer), 4) > 0 loop
l_buffer := l_buffer || replace(replace(dbms_lob.substr(p_clob, 1, l_offset), chr(10), null), chr(13), null);
l_offset := l_offset + 1;
end loop;
l_result := l_result || utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw(l_buffer)));
end loop;
return l_result;
end;
procedure print_clob(p_clob in clob)
as
l_offset number default 1;
begin
loop
exit when l_offset > dbms_lob.getlength(p_clob);
dbms_output.put_line(dbms_lob.substr(p_clob, 4000, l_offset));
l_offset := l_offset + 4000;
end loop;
end;
begin
l_clob := gen_rand_xml;
print_clob(from_base64(to_base64(l_clob)));
end;
/
Пожалуйста, покажите нам свой код. Почему вы пытаетесь преобразовать BLOB в CLOB? Для XML-файла должно быть хорошо работать все в 'CLOB' (если только XML не является UTF-8, но ваша база данных работает на« нижнем »наборе символов, например' WE8ISO8859P1', но тогда вы все равно можете использовать 'NCLOB') –
Когда вы используете 'base64_encode', тогда количество данных должно быть целым кратным 3, т. Е.'l_amt binary_integer: = 1000;' не работает, используйте 'l_amt binary_integer: = 999;' например. –
Изменено количество в скрипте. И для xml с 75 узлами он работал, однако, когда я увеличил количество узлов до 100, он снова не удался. –