尽管长度相同,ORA-12899的值对于色谱柱来说太大了

时间:2016-09-09 06:21:10

标签: sql oracle varchar varchar2

我正在运行以下查询。但得到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)

4 个答案:

答案 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()值中,您可以看到Testing54,65,73,74,69,6e,67)之后,空格和短划线(20,2d)之前c2,a0LENGTHB(column1)=30the 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的地址更改为   可以容纳他们的典型地址长度的金额   公司会输入。

The above answer original URL

答案 3 :(得分:0)

由于目标表数据库中的NLS设置不同,因此目标中可能需要更多字节。 尝试将表格改为     alter table1 modify column1 varchar2(30 char)