我正在尝试在DB2数据库中插入中文文本,但无法正常工作。
默认情况下,数据库配置为ANSI(en_US 819)(这是使用dame数据库的其他应用程序的要求)。定义了ALT_COLLATE IDENTITY_16BIT,并使用CCSID UNICODE创建了UNICODE表,但未插入中文或韩文的Unicode字符。
表格示例:
CREATE TABLE LANGS (
IDIOMA char(2) NOT NULL,
PAIS char(2) NOT NULL,
TRADUC long varchar NOT NULL,
) CCSID UNICODE;
示例插入:
INSERT INTO LANGS (IDIOMA,PAIS,TRADUC) VALUES ('zh','TW','其他');
系统信息:
服务器:Ubuntu 64位上的DB2 9.7(zh_CN)
客户端:具有db2jcc.jar的Windows 7 32位(es_ES)Java 7
Java提取示例:
Class.forName("com.ibm.db2.jcc.DB2Driver");
...
Properties props = new Properties();
props.setProperty("user", user);
props.setProperty("password", pass);
props.setProperty("DB2CODEPAGE", "1208");
props.setProperty("retrieveMessagesFromServerOnGetMessage", "true");
con = DriverManager.getConnection(url, props);
...
Statement statement = con.createStatement();
statement.execute(sql);
...
statement.close();
con.close();
DB CFG取得
DB2数据库语言环境配置
Territorio de base de datos = en_US; Página de códigos de base de datos = 819 Conjunto de códigos de base de datos = iso8859-1 Código de país/región de base de datos = 1 Secuencia de clasificación de base de datos = UNIQUE Orden de clasificación alternativo (ALT_COLLATE) = IDENTITY_16BIT Tamaño de página de base de datos = 4096
Statements are executed correctly and rows appears correctly in the database for:
- en_GB
- en_US
- es_ES
- pt_PT
but not for:
- cy_GB
- ko_KR
- zh_TW
Insert from command line with db2cmd also does not work for this languages (Inserts but with only 1 byte.
Insert from command line in a Linux environment localized as zh_TW works.Insert from command line in a Linux environment localized as en_US.utf-8 works.
Never work on Java on these environments.
Using "X" as prefix form the VARCHAR field is not an option due some restrictions and the SQL works on two environments.
I think it may be some encoding problem on Client, or server due to configuration, file or sql encoding.
Update:
I tried also to load a UTF-8 file with the SQLs. the file loads correctly and debugging the SQL with UTF-8 characters is correctly passed to the Statement but the result is the same.
new InputStreamReader(new FileInputStream(file),"UTF-8")
...
private void executeLineByLine(Reader reader) throws SQLException {
StringBuffer command = new StringBuffer();
try {
BufferedReader lineReader = new BufferedReader(reader);
String line;
while ((line = lineReader.readLine()) != null) {
command = handleLine(command, line);
}
checkForMissingLineTerminator(command);
} catch (Exception e) {
String message = "Error executing: " + command + ". Cause: " + e;
printlnError(message);
throw new SQLException(message, e);
}
}
private StringBuffer handleLine(StringBuffer command, String line) throws SQLException, UnsupportedEncodingException {
String trimmedLine = line.trim();
if (lineIsComment(trimmedLine)) {
println(trimmedLine);
} else if (commandReadyToExecute(trimmedLine)) {
command.append(line.substring(0, line.lastIndexOf(delimiter)));
command.append(LINE_SEPARATOR);
println(command);
executeStatement(command.toString());
command.setLength(0);
} else if (trimmedLine.length() > 0) {
command.append(line);
command.append(LINE_SEPARATOR);
}
return command;
}
private void executeStatement(String command) throws SQLException, UnsupportedEncodingException {
boolean hasResults = false;
Statement statement = connection.createStatement();
hasResults = statement.execute(command);
printResults(statement, hasResults);
statement.close();
}
更新2:
无法更改数据类型。该数据库是其他系统的一部分,并且已经包含数据。
该数据库安装在7台不同的服务器上,其中3台使用Linux在UTF-8 shell中插入数据,并且已从db2命令行正确插入了数据。
从Windows db2命令行或使用Java,无法正确插入字符。
将Java源更改为UTF-8源可以使System.out正确打印SQL,就像我看到调试sql变量一样。
当我插入此测试SQL。可以在System.out和Statement内部变量中正确显示中国字符
INSERT INTO LANGS (IDIOMA,PAIS,TRADUC) VALUES ('zh','TW','TEST1 其他 FIN TEST1');
但是在数据库中,测试显示为:
TEST3 FIN TEST3
十六进制表示:
54 45 53 54 33 20 1A 1A 1A 1A 1A 1A 1A 1A 20 46 49 4E 20 54 45 53 54 33
T E S T 3 _ ? ? ? ? ? ? ? ? _ F I N _ T E S T 3
我认为DB2 Java客户端可能一直使用Windows代码页(在这种情况下为ISO-8859-1或cp1252)而不是UTF-8,或者服务器正在使用主整理而不是表的替代整理来转换数据。
更新3:
我安装了一个名为DbVisualizer的Java SQL工具,并在Windows上使用此工具,当在SQL面板中粘贴SQL并运行SQL并将其正确插入数据库中时。
这使我怀疑这不是安装或数据类型的问题。可能是这三个因素之一。
客户端配置
客户端连接时发送的服务器属性
驱动程序使用的版本类型
最佳答案
使用以下步骤解决了问题:
始终使用db2jcc4.jar而不是db2jcc.jar(JDBC 4)
(在某些地方,JDBC级别2是在OS类路径中使用db2jcc而不是DB2jcc4配置的)
设置环境变量DISABLEUNICODE = 0
此页面Understanding DB2 Universal Database character conversion中有关于DB2上unicode的完整信息。