oracle資料庫字符集為ZHS16GBK插入的韓文日文俄文變成問號
阿新 • • 發佈:2018-11-09
最近專案中解析xml存在中文俄文日文韓文等等亂七八槽的外文,在插入資料庫中會亂碼變成問號。
create or replace function 函式名(引數)
原因:是oracle安裝的資料庫的時候字符集不一樣( select userenv('language') from dual可以檢視),SIMPLIFIED CHINESE_CHINA.ZHS16GBK這種會變成問號,而SIMPLIFIED CHINESE_CHINA.AL32UTF8這種字符集卻可以正常儲存。
嘗試了網上的一些修改環境變數NLS_LANG,以及用nvchar的oracle資料型別卻都不行,存到資料庫都亂碼。最後就只能通過將外文內容轉成十六進位制的位元組碼,最後讀取查詢的時候再將位元組碼轉成原來的內容就行。
public class Test { // 字串轉換unicode public static String string2Unicode(String string) { StringBuffer unicode = new StringBuffer(); for (int i = 0; i < string.length(); i++) { // 取出每一個字元 char c = string.charAt(i); // 轉換為unicode unicode.append("\\u" + Integer.toHexString(c)); } return unicode.toString(); } // unicode 轉字串 public static String unicode2String(String unicode) { StringBuffer string = new StringBuffer(); String[] hex = unicode.split("\\\\u"); for (int i = 1; i < hex.length; i++) { // 轉換出每一個程式碼點 int data = Integer.parseInt(hex[i], 16); // 追加成string string.append((char) data); } return string.toString(); } public static String convert(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)); } public static void main(String[] args) { String str = "???"; System.out.println(convert(str)); System.out.println(string2Unicode(str)); System.out.println(unicode2String(convert(str))); System.out.println(unicode2String(string2Unicode(str))); } } // \ub9ac\uad11\uadfc 輸出結果 // \ub9ac\uad11\uadfc // 리광근 // 리광근
但是我們專案這邊用的是JS查詢,封裝的內部框架,不是去請求Java,所以需要用SQL的函式Function實現oracle函式unistr將Oracle資料庫中的Unicode轉換為原文
函式Function說明:CREATE OR REPLACE FUNCTION UnicodeToString(v_unicode_str varchar2) RETURN nvarchar2 AS v_str nvarchar2(1000) :=''; BEGIN begin select unistr(REPLACE(v_unicode_str,'\u','\')) into v_str from dual ; exception when others then v_str := ''; end; RETURN v_str; END UnicodeToString;
create or replace function 函式名(引數)
return 返回值型別 as
定義變數
begin 函式主體 end
函式Function呼叫:(sql語句,instr判斷有沒有包含\u)
(case when instr(internationalname, '\u') = 1 then UnicodeToString(internationalname) else internationalname end) as internationalname