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



我正在通过resulset从db2表中阅读列字段(char(255((:

String tmp = rs.getString(i);

该字符串在表中长255个字符,但是当我尝试通过插入语句

将此值放入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侧处理。

您是否能够更改NLS_LENGTH_SEMANTICS或扩大目标字段?

nls_length_semantics允许您以字符而不是字节来指定列数据类型的长度。通常,这是使用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修改"时也可以正常工作。

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

Col2 VARCHAR2 (10 CHAR);

限制:实例或会话值仅在创建新列时才会使用。最好避免在同一表中使用字节和字符语义列的混合物。

至于最大宽度,请查看典型的3字节UTF8字符:如果将列定义为Varchar2(1333(char,并且插入1333个字符,则您仍然会获得" ORA-12899:值得太大的值柱子"。在这些情况下,Oracle建议将Varchar2转换为Clob。

您的列是用字节语义定义的,您必须使用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)

请注意,字节语义使得仅存储5个字节,并且插件失败。

alter table tst modify (txt varchar2(5 CHAR));
insert into tst (txt) values('ééééé');
1 row inserted

char语义允许存储5个字符,即使它们占5个字节以上。

最新更新