以下是一些起点。替换所有常规字符相当简单,但控制字符可能有些棘手。该方法使用一个由包含要在其前面添加反斜杠的字符的字符类组成的组。请注意,类内部的字符不需要转义。REGEXP_REPLACE的参数1表示从第一个位置开始,0表示替换源字符串中找到的所有出现。
SELECT REGEXP_REPLACE('t/h"is"'||chr(9)||'is a|te\st', '([/\|"])', '\\\1', 1, 0) FROM dual;
替换制表符和换行符很容易,只需将上述内容包裹在REPLACE调用中即可。但是,每个控制字符都要这样做,这种做法不太好。因此,我担心我的答案并不能完全解决您的问题,它只能帮助您处理一些常规字符:
SQL> SELECT REPLACE(REPLACE(REGEXP_REPLACE('t/h"is"'||chr(9)||'is
2 a|te\st', '([/\|"])', '\\\1', 1, 0), chr(9), '\t'), chr(10), '\n') fixe
3 FROM dual;
FIXED
t\/h\"is\"\tis\na\|te\\st
SQL>
编辑:这里有一个解决方案!我不敢说我完全理解它,但基本上它创建了一个翻译表,连接到您的字符串(在inp_str表中)。 connect by,level遍历字符串的长度,并在翻译表中有匹配项的位置替换字符。我修改了在这里找到的解决方案,但该方案并没有很好地解释。希望这里会有人加入并完全解释一下。
SQL> with trans_tbl(ch_frm, str_to) as (
select '"', '\"' from dual union
select '/', '\/' from dual union
select '\', '\\' from dual union
select chr(8), '\b' from dual union
select chr(12), '\f' from dual union
select chr(10), '\n' from dual union
select chr(13), '\r' from dual union
select chr(9), '\t' from dual
),
inp_str as (
select 'No' || chr(12) || 'w is ' || chr(9) || 'the "time" for /all go\od men to '||
chr(8)||'com' || chr(10) || 'e to the aid of their ' || chr(13) || 'country' txt from dual
)
select max(replace(sys_connect_by_path(ch,'`'),'`')) as txt
from (
select lvl
,decode(str_to,null,substr(txt, lvl, 1),str_to) as ch
from inp_str cross join (select level lvl from inp_str connect by level <= length(txt))
left outer join trans_tbl on (ch_frm = substr(txt, lvl, 1))
)
connect by lvl = prior lvl+1
start with lvl = 1;
TXT
No\fw is \tthe \"time\" for \/all go\\od men to \bcom\ne to the aid of their \rcountry
SQL>
编辑 2016年8月10日 - 把它变成一个函数,以实现封装和可重用性,这样你可以一次性使用它来处理多个列:
create or replace function esc_json(string_in varchar2)
return varchar2
is
s_converted varchar2(4000);
BEGIN
with trans_tbl(ch_frm, str_to) as (
select '"', '\"' from dual union
select '/', '\/' from dual union
select '\', '\\' from dual union
select chr(8), '\b' from dual union
select chr(12), '\f' from dual union
select chr(10), '\n' from dual union
select chr(13), '\r' from dual union
select chr(9), '\t' from dual
),
inp_str(txt) as (
select string_in from dual
)
select max(replace(sys_connect_by_path(ch,'`'),'`')) as c_text
into s_converted
from (
select lvl
,decode(str_to,null,substr(txt, lvl, 1),str_to) as ch
from inp_str cross join (select level lvl from inp_str connect by level <= length(txt))
left outer join trans_tbl on (ch_frm = substr(txt, lvl, 1))
)
connect by lvl = prior lvl+1
start with lvl = 1;
return s_converted;
end esc_json;
同时调用多列的示例:
select esc_json(column_1), esc_json(column_2)
from your_table;
APEX_ESCAPE.JSON
函数。https://docs.oracle.com/cd/E59726_01/doc.50/e39149/apex_escape.htm#AEAPI29608 - Nick