场景:表里面有一大批数据,查询SQL有用到unistr函数,将Unicode编码内容转译后查出。但是却查询报错,ORA-30186: '\' 的后面必须是四个十六进制字符。
尝试:怀疑是存的Unicode编码格式存在问题,用下面的语句并没有发现异常数据
select * from xxx_table where regexp_replace(name,'\\[0-9a-f]{4}','') is not null and instr(name,'\')>0;
解决:写了一段存储过程,发现原来是因为存在中文使得unistr报这种错误
declare
v_str varchar2(1000);
BEGIN
for i in (select namefrom xxx_table) loop
begin
v_str := i.name;
select unistr(i.name) into v_str from dual;
exception
when others then
dbms_output.put_line(v_str);
end;
end loop;
END;
然后,存在错误的内容就蹦出来了,到这里就发现有些中文字通过这个函数竟然会报错诶
SELECT unistr('昞') FROM dual;
SELECT unistr('\661e') FROM dual;
补充:
a.何为Unicode
Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。
b.Java转Unicode
public String StringtoUnicode(String str) {
str = (str == null ? "" : str);
String tmp;
StringBuffer sb = new StringBuffer(1000);
char c;
int i, j;
sb.setLength(0);
for (i = 0; i < str.length(); i++) {
c = str.charAt(i);
sb.append("\\u");
j = (c >>> 8); //取出高8位
tmp = Integer.toHexString(j);
if (tmp.length() == 1)
sb.append("0");
sb.append(tmp);
j = (c & 0xFF); //取出低8位
tmp = Integer.toHexString(j);
if (tmp.length() == 1)
sb.append("0");
sb.append(tmp);
}
return (new String(sb));
}
c.JS转Unicode
function StringtoUnicode(data) {
var regexp = new RegExp("[^\\u4e00-\\u9fa5]");//匹配中文
if(data && regexp.test(data)){
var str = '';
for(var i=0;i<data.length;i++) {
var char = data[i].charCodeAt(0);
var tmp = "";
str += "\\u";
//取出高8位
tmp = parseInt(char >>> 8, 10).toString(16);
if (tmp.length == 1)
str += "0";
str += tmp;
//取出低8位
tmp = parseInt(char & 0xFF, 10).toString(16);
if (tmp.length == 1)
str += "0";
str += tmp;
}
return str;
}
else{
return data;
}
}