我们有一个具有以下字符集设置的 Oracle 数据库
SELECT parameter, value FROM nls_database_parameters WHERE parameter like 'NLS%CHARACTERSET'
NLS_NCHAR_CHARACTERSET: AL16UTF16
NLS_CHARACTERSET: WE8ISO8859P15
在此数据库中,我们有一个带有 CLOB
字段的表,其中包含以以下字符串开头的记录,显然存储在 ISO-8859-15 中:X²ARB
(这里正确转换为unicode,特别是2-上标很重要且正确)。
然后我们使用以下简单的代码来获取值,该代码应该通过 Oracle 中的全局化支持自动将字符集转换为 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
code> 和 ojdbc8.jar
返回正确的值,但这需要对代码进行未知数量的更改,因为这可能不是唯一发生问题的地方。
我可以对客户端或服务器配置做些什么来使所有查询返回正确编码的值而不需要修改语句吗?
最佳答案
它看起来确实像是 JDBC 瘦驱动程序中的一个错误(我假设您使用的是瘦驱动程序)。它可能与 LOB 预取有关,其中 CLOB 的长度、字符集 ID 和 LOB 数据的第一部分是带内发送的。该功能是在 11.2 中引入的。作为解决方法,您可以通过设置连接属性来禁用 lob 预取
oracle.jdbc.defaultLobPrefetchSize
到“-1”。同时我会跟进这个错误以确保它得到修复。
关于java - ojdbc7/ojdbc8 中的字符集问题与 ojdbc6 中的正确行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49374296/