我正在运行以下查询。但得到ORA-12899。尝试插入的字符串的长度是30。
INSERT 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 Corre
Desc temp_Table1
column1 VARCHAR2(30)
Desc Table1
column1 VARCHAR2(30)
答案 0 :(得分:9)
您看到了character and byte length semantics:
之间的区别您必须为VARCHAR2列指定最大长度。尽管存储的实际字符串允许为零长度字符串(''),但此最大值必须至少为1个字节。您可以使用CHAR限定符(例如VARCHAR2(10 CHAR))以字符而不是字节给出最大长度。从技术上讲,字符是数据库字符集的代码点。您可以使用BYTE限定符(例如VARCHAR2(10 BYTE))显式地给出最大长度(以字节为单位)。如果在创建具有此列或属性的数据库对象时,列或属性定义中不包含显式限定符,则长度语义由创建对象的会话的NLS_LENGTH_SEMANTICS参数的值确定。
如果您的会话使用字节语义,那么表中的列将默认为:
select value from nls_session_parameters where parameter = 'NLS_LENGTH_SEMANTICS';
VALUE
----------------------------------------
BYTE
create 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
这与明确做:
create table t42(text varchar2(5 byte));
如果您的源数据是五个字符但包含任何多字节字符,那么 bytes 的数量将超过五个:
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个字节,所以其中一个字符是多字节的。
with 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 hex
from t42;
TEXT CHARS BYTES HEX
------------------------------- ----- ----- ----------------------------------------------------------------------------------------------------------
Hello 5 5 Typ=1 Len=5: 48,65,6c,6c,6f
Señor 5 6 Typ=1 Len=6: 53,65,c3,b1,6f,72
Testing - HLC/TC Design Corre 30 31 Typ=1 Len=31: 54,65,73,74,69,6e,67,c2,a0,20,2d,20,48,4c,43,2f,54,43,20,44,65,73,69,67,6e,20,43,6f,72,72,65
从dump()
值中,您可以看到Testing
(54,65,73,74,69,6e,67
)之后,空格和短划线(20,2d
)之前c2,a0
,LENGTHB(column1)=30
是the UTF-8 multibyte non-breaking space character。 (在Word文档中复制的文本中,您经常会看到,连同卷曲引号和其他非ASCII范围字符。)
您可以更改插入以在drop 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
-
C
insert into t42 (text) values ('Hello');
1 row inserted.
insert into t42 (text) values ('Señor');
1 row inserted.
上进行过滤(这将排除您当前找到的行),或将列定义更改为30个字符而不是30个字节:
System.out.println(ObjectSizeCalculator.getObjectSize(new gnu.trove.map.hash.TObjectIntHashMap<String>(12000, 0.6f, -1)));
System.out.println(ObjectSizeCalculator.getObjectSize(new HashMap<String, Integer>(100000)));
System.out.println(ObjectSizeCalculator.getObjectSize(3));
System.out.println(ObjectSizeCalculator.getObjectSize(new int[]{1, 2, 3, 4, 5, 6, 7 }));
System.out.println(ObjectSizeCalculator.getObjectSize(new int[100]));
或者用单字节等价物替换任何意外的多字节字符,如果可能的话,对你的数据有意义;在这种情况下,正常空间可能可以工作,但是如果有任何替换,您将销毁可能实际上非常重要的信息。
答案 1 :(得分:2)
尝试更改您的表格,如
ALTER TABLE1 MODIFY column1 VARCHAR2(30 CHAR)
该错误表明您的column1最多可存储30个字符,并且您传递的字符数超过30个,从而导致错误。
您还可以参考此文章:Oracle Database - Bytes or Characters for VARCHAR2 and CHAR
答案 2 :(得分:0)
<强> ORA-12899 强>
通常情况下,随着我们公司的成长和发展以应对 以客户群,员工,利润或市场的形式扩张 与此增长相关的数据也将发生变化。数据系统就像 Oracle具有保持相当灵活性的天生能力 处理这种信息差异。尽管如此,甚至是最多的 多功能数据库系统需要维护和改进 面对增加的数据流量。这项工作至关重要 适应对记忆的任何限制或必要的重新定义 参数。 ORA-12899错误代表了一个实例 无论是数据上升还是用户错误都迫使Oracle进入 在请求的行动中失速。
问题
ORA-12899是输入值时发生的Oracle错误 进入列字符串太大。这意味着什么 用户尝试更新或插入具有值的列 对于目标列来说太宽了。特定的名称 将给出列和值的实际宽度,以及 列允许的最大宽度将与之关联。 如上所述,该值可以以字符的形式给出。在里面 以字符报告宽度的事件,这意味着 字符长度语义正在为列操作。否则 width将以字节为单位报告。从本质上讲,这个错误来自 试图推翻超过的价值或价值观 指定列的最大宽度。那么,用户如何纠正 这种错误?
解决方案
首先,打开OERR实用程序。用户将需要完整 ORA-12899消息,以获得有关错误的正确反馈。这个 将提供有关错误的更多信息并允许进一步 调查。通常,错误可能来自三个中的一个 源。第一个来源是已经存在的SQL语句 产生。检查源和目标列数据类型 发现它们是否与当前格式兼容 第二个来源。最后,用户可以查看目标列 width - 分配值的位置 - 确保它很大 足以容纳用户预期的最大价值 分配。现在让我们转向修正ORA-12899的示例。 假设用户已创建下表:
CREATE TABLE Clients( ClientID varchar2(9) PRIMARY KEY, Client_Contact varchar2(40) NOT NULL, Address varchar(20) NOT NULL, Zip varchar2(5) NOT NULL, Client_Number varchar2(11) NOT NULL)
然后,用户尝试发出一个看起来的INSERT VALUES语句 像这样的东西:
INSERT INTO Clients VALUES( 727546345, ‘Roger Holcomb’, ‘—Benjamin Road Syracuse’, ‘-----‘, 05307623754)
用户可能会尝试从此处运行语句,但会收到 以下错误消息:
从命令行第7行开始出错:INSERT INTO Clients VALUES(727546345,'Ricky Galorey','18 Benjamin Road Syracuse', '13208',05307623754)错误报告:SQL错误:ORA-12899:值也是 列“组织”大。 “市场”。 “ADDRESS”(实际:25, 最大值:20)12899。00000 - “对于列%s来说值太大(实际: %s,最大值:%s)“
此错误语句表示变量“地址”无法保存 超过二十个字符,超过了宽度 列参数。当我们回顾地址价值时('18本杰明 Road Syracuse')我们可以看到总字符数(25) 超过列宽度允许的最大数量。至 更正此问题,用户可以将VARCHAR2的地址更改为 可以容纳他们的典型地址长度的金额 公司会输入。
答案 3 :(得分:0)
由于目标表数据库中的NLS设置不同,因此目标中可能需要更多字节。 尝试将表格改为 alter table1 modify column1 varchar2(30 char)