当前位置: 首页 > 面试题库 >

尽管长度相同,ORA-12899的值对于列还是太大

谢墨竹
2023-03-14
问题内容

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

问题答案:

您会看到字符和字节长度语义之间的区别:

您必须为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));

如果您的源数据是五个字符但包含任何多字节字符,则 字节 数将超过五个:

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,a0,这是UTF-8多字节不间断空格字符。(您经常会在从(例如)Word文档复制的文本中看到,连同弯引号和其他非ASCII范围的字符)。

您可以更改插入内容以进行过滤LENGTHB(column1)=30(将排除当前找到的行),也可以将列定义更改为30个字符而不是30个字节:

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.

或者,如果有可能并且对您的数据有意义,请用单字节等效项替换任何意外的多字节字符。在这种情况下,正常的空间 可能会
起作用,但是如果进行任何替换,您将破坏实际上可能很重要的信息。



 类似资料:
  • 问题内容: 我已经创建了下表 而且我目前正在尝试使用INSERT VALUES语句。我写了以下声明 当我尝试运行该语句时,它会显示以下错误消息。 从命令的第4行开始错误:插入客户值(501623129,“ David Patterson”,“ 30 Singleton Close London”,“ SW17 9JY”,02082860642)错误报告:SQL错误:ORA-12899:列“”的值太

  • 在阅读equals()和hashcode()时,我了解到,如果两个对象相等,那么它们的hashcode必须相等,反之亦然。 但是下面的例子并没有反映这一点。 如果是,则返回true,即使它们的哈希代码不同,这从打印和中可以明显看出。 有人能给我解释一下吗?

  • 我是Grails新手,不太熟悉GORM如何将列映射到jdbc实现。基本上我有以下错误: 组织。h2.jdbc。JdbcSQLException 消息: “KEYWORDS BINARY(255)”列的值太长:“X'ACED0005737200116A6176612E7574696C2E486173684D61700507DAC131660D1030002460A6C6F6164466163746F

  • 我使用的是Spring Data JPA,我的列定义是 在有效负载中,我使用了具有字符计数的描述。但它仍然在扔 错误:值太长,无法更改类型字符(255)` 仅使用长度为1990的文本,即使对于文本类型也会出现相同的错误

  • 我在持久化LocalDate字段[在列中使用VARCHAR(20)类型]时收到以下错误: 字段定义如下: 我使用的是spring data starter(1.5.9版本)。它在内部使用hibernate 5.0.12。 根据博文https://www.thoughts-on-java.org/hibernate-5-date-and-time/ Hibernate 5,支持Java 8特性(Da

  • 问题内容: 在使用pygame编写的图形程序中,我使用表示如下坐标的元组:(50,50)。 有时,我调用一个函数,该函数返回另一个元组,例如(3,-5),它表示坐标的变化。 将更改值添加到坐标值的最佳方法是什么。如果可以做一些坐标+ = change的工作,那将是很好的选择,但是看起来这将把两个元组简单地连接为(50,50,3,-5)之类的东西。而不是将第一个值与第一个值相加,将第二个值与第二个值