我们有一个具有以下字符集设置的Oracle数据库
SELECT参数,值FROM nls_database_parameters WHERE参数,如'NLS%CHARACTERSET'
NLS_NCHAR_CHARACTERSET: AL16UTF16
NLS_CHARACTERSET: WE8ISO8859P15
在这个数据库中,我们有一个带有CLOB
字段的表,该字段的记录以下面的字符串开头,显然存储在ISO-8859-15中:X²ARB
(这里正确转换为unicode) ,特别是2-superscript是重要且正确的。)
然后我们有以下微不足道的代码来获取值,这应该通过Oracle中的全球化支持自动将charset转换为unicode:
private static final String STATEMENT = "SELECT data FROM datatable d WHERE d.id=2562456";
public static void main(String[] args) throws Exception {
Class.forName("oracle.jdbc.driver.OracleDriver");
try (Connection conn = DriverManager.getConnection(DB_URL);
ResultSet rs = conn.createStatement().executeQuery(STATEMENT))
{
if (rs.next()) {
System.out.println(rs.getString(1).substring(0, 5));
}
}
}
运行代码打印:
ojdbc8.jar
和orai18n.jar
:X�ARB
- 错误ojdbc7.jar
和orai18n.jar
:X�ARB
- 错误ojdbc-6.jar
:X²ARB
- 正确 使用UNISTR
并将语句更改为SELECT UNISTR(data) FROM datatable d WHERE d.id=2562456
我可以使ojdbc7.jar
和ojdbc8.jar
返回正确的值,但这需要进行未知数量的更改这个代码可能不是问题发生的唯一地方。
我可以对客户端或服务器配置做些什么来使所有查询返回正确编码的值而不进行语句修改?
答案 0 :(得分:3)
它看起来像JDBC瘦驱动程序中的一个错误(我假设您正在使用瘦)。它可能与LOB预取有关,其中CLOB的长度,字符集id和LOB数据的第一部分是在带内发送的。此功能在11.2中引入。作为解决方法,您可以通过设置连接属性
来禁用lob预取oracle.jdbc.defaultLobPrefetchSize
到" -1"。与此同时,我将跟进此错误,以确保它得到修复。
答案 1 :(得分:-1)
请查看Database JDBC Developer's Guide - Globalization Support
基本Java Archive(JAR)文件ojdbc7.jar,包含所有 必要的课程,以提供全面的全球化支持:
对象和集合的
CHAR
或VARCHAR
数据成员,用于字符集US7ASCII
,WE8DEC
,WE8ISO8859P1
,WE8MSWIN1252
和{ {1}}。使用
UTF8
或CHAR
个数据成员中的任何其他字符集 对象或集合,您必须在VARCHAR
中包含orai18n.jar 环境变量:
CLASSPATH