由于不同的字符集,无法通过Java将数据从DB2复制到Oracle

时间:2017-05-29 09:30:29

标签: java oracle character-encoding

我正在通过resulSet:

从DB2表中读取一个列字段(char(255))
String tmp = rs.getString(i);

该字符串在表中长度为255个字符,但是当我尝试通过insert语句将此值放入Oracle列(char(255))时

insertStmt.setString(j,tmp);

我得到一个SQL异常:

ORA-12899: value too large for column "[schema_name]"."[table_name]"."[column_name]" (current: 258, max: 255)

我可以看到

tmp.getBytes("UTF-8").length

是258,因为三个“è”字符使用两个字节而不是一个。

如何成功将此字符串转换/插入Oracle表? 从Oracle db我可以阅读

NLS_CHARACTERSET    AL32UTF8

但是我无法在Java端处理它。

2 个答案:

答案 0 :(得分:0)

您是否可以更改NLS_LENGTH_SEMANTICS或扩大目标字段?

NLS_LENGTH_SEMANTICS允许您根据CHARacters而不是BYTE指定列数据类型的长度。通常,这是在使用AL32UTF8或UTF8或其他宽度不同的NLS_CHARACTERSET数据库时,其中一个字符并不总是一个字节。

如果未在数据库级别定义,则可以在会话级别设置。

ALTER SESSION SET NLS_LENGTH_SEMANTICS=BYTE

Oracle建议在创建表时明确使用CHAR。

Create table scott.test (Col1 CHAR(20 CHAR),Col2 VARCHAR2(100 CHAR));

导入或使用'alter table modify'时也可以。

访问PL / SQL中的列时,请明确定义变量,例如

Col2 VARCHAR2 (10 CHAR);

限制: 实例或会话值仅在创建NEW列时使用。 最好避免在同一个表中使用BYTE和CHAR语义列的混合。

至于最大宽度,查看一个典型的3字节UTF8字符:如果将列定义为varchar2(1333)CHAR并且插入超过1333个字符,则仍会得到“ORA-12899:值太大而无法使用柱”。在这些情况下,oracle建议将varchar2转换为CLOB。

答案 1 :(得分:0)

您的列定义为BYTE semantic,您必须使用DDL切换到CHAR语义,例如:

alter table tst modify (txt varchar2(5 CHAR));

小例子:

create table tst
(txt varchar2(5));

insert into tst (txt) values('ééééé');
-- SQL-Fehler: ORA-12899: value too large for column "REPORTER"."TST"."TXT" (actual: 10, maximum: 5)

请注意,BYTE语义只能存储5个字节,插入失败。

alter table tst modify (txt varchar2(5 CHAR));

insert into tst (txt) values('ééééé');

1 row inserted

CHAR语义允许存储5个字符,即使它们占用超过5个字节。