我有一個大小約爲3.5mb的xml文件。我encuding它並傳播到另一個數據庫,我需要解碼它。我在迭代中對它進行解碼,因爲它太大而無法一次解碼,但是在某些迭代中它無法解碼,我得到了一些giberish。我相信這是因爲一些符號可以是1個字節,其他符號可以是2個字節,有時子字符串會將2個字節的一個符號切成兩半,並且這個迭代會出現在giberish中。我認爲我可以嘗試將每個子字符串轉換爲clob,因爲它在轉換失敗時出現警告,如果出現警告,通過某個數字增加子字符串中的數量,我還沒有成功解碼這個辦法。有沒有解決方法?解碼大的base64編碼斑點
UPDATE
成功地解碼,但有警告的檢查。所有你需要做的就是嘗試將substring轉換爲clob,使用dbms_lob.convertblobtoclob
檢查warning != 0
,如果是這樣,則將偏移減少1並轉到下一次迭代,而不將子串寫入blob。然而,這是非常複雜的檢查,因爲它需要創建blob並將該blob轉換爲clob。有沒有更簡單的解決方法,也許我錯過了非常明顯的東西?
UPDATE
我已經包含支付XML中base64編碼,以及有關XML其他數據的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;'。 –
更改腳本中的金額。對於具有75個節點的xml,它可以工作,但是當我將節點數量增加到100時,它再次失敗。 –