在西方字符集的Oracle数据库上用Java操作UTF8数据

虽然Oracle推荐建立一个新的Oracle instance的时候最好选用AL32UTF8作为默认的字符集,这样可以更好的来支持国际化的各种语言字符集的数据。可是还是由于各种各样的历史原因,有一些Oralce数据库的instance还是用的默认的西方字符集。在这样的数据库下面,对于UTF8数据的更新,要进行一些额外的操作。

本文测试所用的Oracle数据库的NLS信息如下
  • NLS_LANGUAGE                  
    AMERICAN
  • NLS_CHARACTERSET              
    WE8ISO8859P1
  • NLS_NCHAR_CHARACTERSET        
    UTF8


数据库的表字段选用了NVARCHAR2。

CREATE TABLE UTF8TEST (
  LABEL  NVARCHAR2(128)
);



使用的Oracle客户端是Oracle SQL Developer,这个是Oracle自家出的基于Java的客户端,默认对于多语言的select操作支持比较好,可以直接选出UTF8的数据。但是如果insert或是update的话,还是产生了乱码数据。

INSERT INTO UTF8TEST VALUES ('中文测试');

SELECT * FROM UTF8TEST;


------

LABEL                                                                                                                          
-------
¿¿¿¿  


如果用java/groovy程序,也会产生同样的乱码。用的JDBC Driver是ojdbc14.jar
def db = [
  url:'jdbc:oracle:thin:@XXX',
  user:'XXX',
  password:'XXX',
  driver:'oracle.jdbc.driver.OracleDriver']

def sql = Sql.newInstance(db.url, db.user, db.password, db.driver)

sql.execute("INSERT INTO UTF8TEST VALUES ('中文测试')")

sql.close()


解决的方案,在运行程序的时候加入JVM的参数
-Doracle.jdbc.defaultNChar=true -Doracle.jdbc.convertNcharLiterals=true


Oracle的文档中有如下的说法:
引用

By default, the oracle.jdbc.OraclePreparedStatement interface treats the data type of all the columns in the same way as they are encoded in the database character set. However, since Oracle Database 10g, if you set the value of oracle.jdbc.defaultNChar system property to true, then JDBC treats all character columns as being national-language.


意思是说默认的话,程序jdbc用的是char的映射,只有当设置了JVM System property后,可以默认映射成NCHAR, NVARCHAR, NCLOB。

oracle.jdbc.convertNcharLiterals这个配置可以,用这如下的方法来操作
INSERT INTO UTF8TEST VALUES (N'中文测试');


你可能感兴趣的:(java,oracle,utf8)