Posted on 2006-04-20 10:46
Terry的Blog 閱讀(3669)
評論(0) 編輯 收藏 所屬分類:
oracle
在一般的日文字符表示正常的情況下正波浪線“~”任然經(jīng)常會出現(xiàn)亂碼的情況。
數(shù)據(jù)庫參數(shù)NLS Database Parameters
NLS_CHARACTERSET?????????????????? JA16SJIS
NLS_NCHAR_CHARACTERSET?? AL16UTF16
一:對于VARCHAR2字段
現(xiàn)象:在頁面上輸入“~”存入DB后再取出到頁面時變成“?”(頁面的字符設(shè)置為charset=shift-jis)
調(diào)查:
1 頁面提交后在java中觀察編碼為\uff5e
2 java中定義一個字符變量“~”觀察編碼為\uff5e
3 編碼為\uff5e的字符存入數(shù)據(jù)庫再取出的編碼為\u301c
4?用Object Browser觀察數(shù)據(jù)庫中字符都正常
結(jié)論:存入數(shù)據(jù)庫時編碼發(fā)生了變化\uff5e ---> \u301c
解決:取出數(shù)據(jù)時遍歷發(fā)現(xiàn)\u301c就轉(zhuǎn)換為\uff5e
????? public String getString(int columnIndex) throws SQLException {
???????? // TODO: ~を変更
???????? String value = rs.getString(columnIndex);
???????? if (value != null){
????????????? StringBuffer sbDest = new StringBuffer();
????????????? char ch;
????????????? for(int j= 0;j< value.length();j++){
????????????????? ch = value.charAt(j);
????????????????? if(ch == 0x301c){
????????????????????? sbDest.append("\uff5e"); // ~
????????????????? }else{
????????????????????? sbDest.append(ch);
????????????????? }
????????????? }
????????????? value = sbDest.toString();
???????? }
???????? return value;
???? }
二:對于NVARCHAR2字段
現(xiàn)象:在頁面上輸入正波浪線“~”存入DB后再取出到頁面時變成反波浪線“?”(頁面的字符設(shè)置為charset=UTF-8)
用Object Browser工具察看表中的數(shù)據(jù) 發(fā)現(xiàn)是正波浪線“~” 編碼為\u301c。(實(shí)際上用Object Browser看\u301c? \uff5e都是正波浪線)
如果用NVARCHAR2字段,那么正確的操作后可以存入\uff5e
試驗(yàn)用表?Products ,表中的列定義如下所示
id - VARCHAR2(10) — 產(chǎn)品 id
lang_id — VARCHAR2(10) — 語言 id
description — NVARCHAR2(2000) — Unicode 編碼的產(chǎn)品描述
JDBC 允許 Java 程序訪問 Oracle9i 數(shù)據(jù)庫中的 NVARCHAR2 數(shù)據(jù)類型的列。Oracle JDBC 驅(qū)動程序把 SQL NCHAR/NVARCHAR2 列中的數(shù)據(jù)從本地字符集編碼(UTF8 或 AL16UTF16)直接轉(zhuǎn)化為 UTF-16 編碼的 Java 字符串。
為此,我們需要把 Java 字符串綁定到一個 NVARCHAR2 列。下面的代碼段顯示了完成這項(xiàng)任務(wù)的代碼。
// Get an Oracle preparedstatement
OraclePreparedStatement orastmt =(OraclePreparedStatement)connection.prepareStatement(
"INSERT INTO PRODUCTS VALUES(?,?,?)");
// Bind the 3rd parameter to NVARCHAR2 form so that the data is stored as unicode
orastmt.setFormOfUse(3,OraclePreparedStatement.FORM_NCHAR);
orastmt.setString(1,product.getId());
orastmt.setString(2,product.getLangId());
orastmt.setString(3,product.getDescription());
orastmt.executeUpdate();
orastmt.close();
使用 orastmt.setFormOfUse() 方法來指定列的類型是 NVARCHAR2。確保數(shù)據(jù)以Unicode 編碼存儲。
關(guān)于NVARCHAR2字段的操作參考:
http://www.oracle.com/technology/sample_code/tech/java/sqlj_jdbc/files/9i_jdbc/NCHARsupport4UnicodeSample/Readme.html
注意這段話:
The only difference in usage between the SQL CHAR and SQL NCHAR datatypes occur in a data bind situation.
The JDBC program must call the setFormOfUse() method to specify if the data is bound for a SQL NCHAR
datatype and it must be called before binding Java variables to SQL NCHAR datatypes.
必須先setFormOfUse再綁定變量。否則存入數(shù)據(jù)庫中的仍是\u301c