|
我正在运行以下查询。但是我得到了。ORA-12899。试图插入的字符串总长度为30。
- k% R5 h, }' ^7 N1 W9 W# wINSERT INTO TABLE1 SELECT * FROM temp_Table1 where LENGTH(column1)=30;SQL Error: ORA-12899:value too large for column "TABLE1"."column1" (actual: 31,maximum: 30)select column1 from temp_Table1 where LENGTH(column1)=30;Testing听 - HLC/TC Design CorreDesc temp_Table1column1 VARCHAR2(30)Desc Table1column1 VARCHAR2(30) / L* x* e( Z |* s; L9 l
解决方案:
6 c0 H" m" r, H 您可以看到字符和字节长度语义的区别:
: ]% T; a8 v. _- R$ N您必须为VARCHAR2列指定最大长度。虽然允许存储的实际字符串是零长度字符串(’‘),但最大值必须至少一个字节。你可以用它CHAR例如,限定符VARCHAR2(10
* l$ a! L0 h8 b g7 U9 TCHAR),最大长度由字符(而不是字节)提供。从技术上讲,字符是数据库字符集的代码点。您可以使用它BYTE例如,限定符VARCHAR2(10
, c5 c7 {0 v: w7 B) c) `BYTE),以字节为单位,给出最大长度。如果在创建具有该列或属性的数据库对象时,列或属性定义中没有包含任何明确的限长度语义由创建对象的对话NLS_LENGTH_SEMANTICS确定参数值。+ U7 p3 B% o1 L. K+ H W, l
若您的会话使用字节语义,则表中的列将默认为:; T3 m! O/ I8 S/ [
select value from nls_session_parameters where parameter = 'NLS_LENGTH_SEMANTICS';VALUE ----------------------------------------BYTEcreate table t42(text varchar2(5));Table T42 created.select char_used from user_tab_columns where table_name = 'T42' and column_name = 'TEXT';C-B这与显式执行相同:0 a( X; C7 S- s
create table t42(text varchar2(5 byte));如果您的源数据是五个字符,但包含任何多字节字符, 字节 数将超过五个:- O. M4 K+ M. m7 E) o- D# f
insert into t42 (text) values ('Hello');1 row inserted.insert into t42 (text) values ('Se帽or');SQL Error: ORA-12899: value too large for column "SCHEMA"."T42"."TEXT" (actual: 6,maximum: 5)这就是你所看到的。当你从其他表中插入值时,你会根据值的长度过滤,但它会length()计算字符而不是字节。lengthb()函数可以计算字节数。如果你检查所选30个字符的字节长度,你会发现它实际上是31个字节,所以其中一个字符是多字节。
1 r3 S, g; i) B6 I: kwith t42 (text) as ( select 'Hello' from dual union all select 'Se帽or' from dual union all select 'Testing听 - HLC/TC Design Corre' from dual)select text,length(text) as chars,lengthb(text) as bytes,dump(text,16) as hexfrom t42;TEXT CHARS BYTES HEX ------------------------------- ----- ----- ----------------------------------------------------------------------------------------------------------Hello 5 5 5 5 5 5 5 5 5 Typ=1 Len=5: 48,65,6c,6c,6f Se帽or 5 5 5 5 5 5 Typ=1 Len=6: 53,65,c3,b1,6f, Testing听 - HLC/TC Design Corre 30 31 31 31 Typ=1 Len=31: 54,65,73,74,69e,67,c2,a0,20,2d,20,48,4c,43,2f,54、43、20、44、65、73、69、67e,20,43,6f,72,72,65从这些dump()值中可以看到Testing(54,65,73,74,69e,67)之后,空格和破折号(20,20d)之前c2,a0,这是UTF-8多字节不间断空格字符(例如)Word从文档复制的文本中可以看到,与弯引号和其他非非文件一起ASCII范围字符)。* s2 T& j' ], f2 M
您可以更改插入内容进行过滤LENGTHB(column1)=30(排除目前发现的行)也可以将列定义改为30个字符,而不是30个字节:
& Q+ R4 r/ D, O* P/ x) j3 x# p- q/ S: Vdrop table t42;Table T42 dropped.create table t42(text varchar2(5 char));Table T42 created.select char_used from user_tab_columns where table_name = 'T42' and column_name = 'TEXT';C-Cinsert into t42 (text) values ('Hello');1 row inserted.insert into t42 (text) values ('Se帽or');1 row inserted.或者,如果可能且对您的数据有意义,请用单字节等效项替换任何意想不到的多字节字符。在这种情况下,正常空间 可能会
0 E7 N# `, ^* s% W2 j0 b L1 e它起作用,但如果进行任何替换,实际上可能会破坏重要的信息。 |
|