Oracle PL/SQL utl_url.escape clob
Oracle PL/SQL utl_url.escape clob
我有一个大的 BLOB 对象,我需要用编码字符将其转换为 base64 中的 CLOB,我尝试使用 utl_encode.base64_encode但它不会转义 ={}+@~ 等特殊字符。有谁知道如何用 utl_url.escape 转义那些特殊字符?我的代码:
PROCEDURE base64encode ( i_blob in blob, io_clob in out nocopy clob) IS
l_step pls_integer := 22500;
l_converted VARCHAR2(32767);
l_buffer_size_approx pls_integer := 1048576;
l_buffer CLOB;
BEGIN
dbms_lob.createtemporary(l_buffer, TRUE, dbms_lob.call);
FOR i IN 0 .. trunc((dbms_lob.getlength(i_blob) - 1 )/l_step)
LOOP
l_converted := utl_raw.cast_to_varchar2(utl_encode.base64_encode(dbms_lob.substr(i_blob, l_step, i * l_step + 1)));
dbms_lob.writeappend(l_buffer, length(l_converted), l_converted);
IF dbms_lob.getlength(l_buffer) >= l_buffer_size_approx THEN
dbms_lob.append(io_clob, l_buffer);
dbms_lob.trim(l_buffer, 0);
END IF;
END LOOP;
dbms_lob.append(io_clob, l_buffer);
dbms_lob.freetemporary(l_buffer);
END base64encode;
如果我尝试将 BLOB 转换为 base64,它会给我这样的输出:
8J5G7Ty8t3Pn7T+9ce/+w/c//nn/Jd1VDTKhadyLoNKDDx/Cl+4/SHN7jFjSVFrj <- 不是完整的 base64 只是单行,
但我需要这样的输出,带有转义字符:
8J5G7Ty8t3Pn7T%2B9ce%2F%2Bw%2Fc%2F%2Fnn%2FJd1VDTKhadyLoNKDDx%2FCl%2B4%2FSHN7jFjSVFrj
结果是大的 CLOB 文本,不适合 varchar2 变量。
APEX_UTIL.URL_ENCODE
可能会成功。
SELECT APEX_UTIL.URL_ENCODE('8J5G7Ty8t3Pn7T+9ce/+w/c//nn/Jd1VDTKhadyLoNKDDx/Cl+4/SHN7jFjSVFrj')
FROM dual;
输出:
8J5G7Ty8t3Pn7T%2B9ce%2F%2Bw%2Fc%2F%2Fnn%2FJd1VDTKhadyLoNKDDx%2FCl%2B4%2FSHN7jFjSVFrj
所以我想出了一个可行的解决方案,此代码解码 base64 clob 并转义保留字符。它有点慢,但它完成了工作。首先,你需要从我的主要问题中调用 base64encode 函数,然后将 clob 传递给这个函数。我希望它也能帮助到其他人。
FUNCTION encode64_clob(in_clob CLOB) RETURN CLOB IS
temp_chunk VARCHAR(4000);
l_enter NUMBER := 1;
l_old_ent NUMBER := 1;
l_ent_cnt NUMBER := 1;
l_out CLOB;
BEGIN
LOOP
l_enter := instr(in_clob, chr(10), 1, l_ent_cnt);
IF l_enter = 0 THEN
temp_chunk := regexp_replace(substr(in_clob, l_old_ent, length(in_clob)), '[[:space:]]+', '');
l_out := l_out || temp_chunk;
EXIT;
END IF;
temp_chunk := regexp_replace(substr(in_clob, l_old_ent, l_enter - l_old_ent), '[[:space:]]+', '');
temp_chunk := utl_url.escape(url => temp_chunk, escape_reserved_chars => TRUE, url_charset => 'UTF-8');
l_out := l_out || temp_chunk;
l_ent_cnt := l_ent_cnt + 1;
l_old_ent := l_enter;
END LOOP;
RETURN l_out;
END;
我有一个大的 BLOB 对象,我需要用编码字符将其转换为 base64 中的 CLOB,我尝试使用 utl_encode.base64_encode但它不会转义 ={}+@~ 等特殊字符。有谁知道如何用 utl_url.escape 转义那些特殊字符?我的代码:
PROCEDURE base64encode ( i_blob in blob, io_clob in out nocopy clob) IS
l_step pls_integer := 22500;
l_converted VARCHAR2(32767);
l_buffer_size_approx pls_integer := 1048576;
l_buffer CLOB;
BEGIN
dbms_lob.createtemporary(l_buffer, TRUE, dbms_lob.call);
FOR i IN 0 .. trunc((dbms_lob.getlength(i_blob) - 1 )/l_step)
LOOP
l_converted := utl_raw.cast_to_varchar2(utl_encode.base64_encode(dbms_lob.substr(i_blob, l_step, i * l_step + 1)));
dbms_lob.writeappend(l_buffer, length(l_converted), l_converted);
IF dbms_lob.getlength(l_buffer) >= l_buffer_size_approx THEN
dbms_lob.append(io_clob, l_buffer);
dbms_lob.trim(l_buffer, 0);
END IF;
END LOOP;
dbms_lob.append(io_clob, l_buffer);
dbms_lob.freetemporary(l_buffer);
END base64encode;
如果我尝试将 BLOB 转换为 base64,它会给我这样的输出: 8J5G7Ty8t3Pn7T+9ce/+w/c//nn/Jd1VDTKhadyLoNKDDx/Cl+4/SHN7jFjSVFrj <- 不是完整的 base64 只是单行,
但我需要这样的输出,带有转义字符:
8J5G7Ty8t3Pn7T%2B9ce%2F%2Bw%2Fc%2F%2Fnn%2FJd1VDTKhadyLoNKDDx%2FCl%2B4%2FSHN7jFjSVFrj
结果是大的 CLOB 文本,不适合 varchar2 变量。
APEX_UTIL.URL_ENCODE
可能会成功。
SELECT APEX_UTIL.URL_ENCODE('8J5G7Ty8t3Pn7T+9ce/+w/c//nn/Jd1VDTKhadyLoNKDDx/Cl+4/SHN7jFjSVFrj')
FROM dual;
输出:
8J5G7Ty8t3Pn7T%2B9ce%2F%2Bw%2Fc%2F%2Fnn%2FJd1VDTKhadyLoNKDDx%2FCl%2B4%2FSHN7jFjSVFrj
所以我想出了一个可行的解决方案,此代码解码 base64 clob 并转义保留字符。它有点慢,但它完成了工作。首先,你需要从我的主要问题中调用 base64encode 函数,然后将 clob 传递给这个函数。我希望它也能帮助到其他人。
FUNCTION encode64_clob(in_clob CLOB) RETURN CLOB IS
temp_chunk VARCHAR(4000);
l_enter NUMBER := 1;
l_old_ent NUMBER := 1;
l_ent_cnt NUMBER := 1;
l_out CLOB;
BEGIN
LOOP
l_enter := instr(in_clob, chr(10), 1, l_ent_cnt);
IF l_enter = 0 THEN
temp_chunk := regexp_replace(substr(in_clob, l_old_ent, length(in_clob)), '[[:space:]]+', '');
l_out := l_out || temp_chunk;
EXIT;
END IF;
temp_chunk := regexp_replace(substr(in_clob, l_old_ent, l_enter - l_old_ent), '[[:space:]]+', '');
temp_chunk := utl_url.escape(url => temp_chunk, escape_reserved_chars => TRUE, url_charset => 'UTF-8');
l_out := l_out || temp_chunk;
l_ent_cnt := l_ent_cnt + 1;
l_old_ent := l_enter;
END LOOP;
RETURN l_out;
END;