You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.6 KiB
51 lines
1.6 KiB
1 year ago
|
-- https://stackoverflow.com/questions/19539408/error-when-decoding-base-64-to-blob
|
||
|
CREATE OR REPLACE FUNCTION base64_decode(p_content CLOB) RETURN BLOB
|
||
|
IS
|
||
|
C_CHUNK_SIZE CONSTANT INTEGER := 4000; -- should be a multiple of 4
|
||
|
C_NON_BASE64_SYM_PATTERN CONSTANT VARCHAR2(20) := '[^A-Za-z0-9+/]';
|
||
|
l_chunk_buf VARCHAR2(4000);
|
||
|
l_chunk_b64_buf RAW(3000);
|
||
|
l_chunk_offset INTEGER := 1;
|
||
|
l_chunk_size INTEGER;
|
||
|
l_res BLOB;
|
||
|
|
||
|
FUNCTION get_next_full_base64_chunk(l_data CLOB, p_cur_pos IN OUT INTEGER, p_desired_size INTEGER, p_cur_size IN OUT INTEGER) RETURN VARCHAR2 IS
|
||
|
l_res VARCHAR2(4000);
|
||
|
l_tail_desired_size INTEGER;
|
||
|
BEGIN
|
||
|
l_res := dbms_lob.substr(l_data, p_desired_size, p_cur_pos);
|
||
|
p_cur_pos := p_cur_pos + p_desired_size;
|
||
|
IF l_res IS NULL THEN
|
||
|
RETURN NULL;
|
||
|
END IF;
|
||
|
|
||
|
l_res := regexp_replace(l_res, C_NON_BASE64_SYM_PATTERN, '');
|
||
|
p_cur_size := p_cur_size + length(l_res);
|
||
|
|
||
|
l_tail_desired_size := 4 - mod(p_cur_size, 4);
|
||
|
IF l_tail_desired_size = 4 THEN
|
||
|
RETURN l_res;
|
||
|
ELSE
|
||
|
RETURN l_res || get_next_full_base64_chunk(l_data, p_cur_pos, l_tail_desired_size, p_cur_size);
|
||
|
END IF;
|
||
|
END;
|
||
|
|
||
|
BEGIN
|
||
|
dbms_lob.createtemporary(l_res, false);
|
||
|
|
||
|
WHILE true
|
||
|
LOOP
|
||
|
l_chunk_size := 0;
|
||
|
l_chunk_buf := get_next_full_base64_chunk(p_content, l_chunk_offset, C_CHUNK_SIZE, l_chunk_size);
|
||
|
EXIT WHEN l_chunk_buf IS NULL;
|
||
|
l_chunk_b64_buf := utl_encode.base64_decode(utl_raw.cast_to_raw(l_chunk_buf));
|
||
|
dbms_lob.writeappend(l_res, utl_raw.length(l_chunk_b64_buf), l_chunk_b64_buf);
|
||
|
END LOOP;
|
||
|
|
||
|
RETURN l_res;
|
||
|
END;
|
||
|
/
|
||
|
DECLARE
|
||
|
l_clob CLOB;
|
||
|
BEGIN
|