我正在通过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端处理它。
答案 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个字节。