ORA-12899 值对于列来说太大,尽管长度相同

2023-12-22

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

你看到了之间的区别字符和字节长度语义 http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements001.htm#i45694:

您必须指定 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,即UTF-8 多字节不间断空格字符 http://www.fileformat.info/info/unicode/char/00a0/index.htm。 (您经常会在从 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.

或者,如果可能并且对您的数据有意义,则将任何意外的多字节字符替换为单字节等效字符;在这种情况下是一个正常的空间might工作,但任何替代都会破坏实际上可能很重要的信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ORA-12899 值对于列来说太大,尽管长度相同 的相关文章

  • 递归 SQL 给出 ORA-01790

    使用 Oracle 11g 第 2 版 以下查询给出 ORA 01790 表达式必须与相应表达式具有相同的数据类型 with intervals time interval AS select trunc systimestamp from
  • SqlCommand 参数与 String.Format [重复]

    这个问题在这里已经有答案了 我一直在互联网上搜索 但似乎找不到任何可以解释我的问题的内容 可能是我没有使用正确的搜索字符串 所以我在这里发帖希望有人可以帮助我有了这个 我的程序是使用Visual Studio 2010用C 编写的 我注意到
  • Sql Server:如何在 WHERE 子句中使用 MAX 等聚合函数

    我想获得该记录的最大值 请帮我 SELECT rest field1 FROM mastertable AS m INNER JOIN SELECT t1 field1 field1 t2 field2 FROM table1 AS T1
  • 使用 WHILE 创建虚拟数据

    我尝试使用 a 在表中插入一些虚拟数据WHILE 但它运行得非常非常慢 我在想也许我写的代码不正确 你能看一下并确认一下吗 Insert dummy data DECLARE i int Content int SET i 5001 WHI
  • Oracle 9i:同义词表不存在?

    我创建了一个包 其中包含一个存储过程 我计划从单独的应用程序调用该存储过程 存储过程将返回架构中所有视图和表的排序列表 为此 它对 DBA TABLES 和 DBA VIEWS 同义词执行简单的选择 如下所示 CREATE OR REPLA
  • java.sql.Timestamp 到微秒精度的字符串

    我正在将时间戳列从数据库读取到 java sql Timestamp 对象中 然后我想将时间戳的值转换为 String 对象 但保持微秒精度 调用 toString 方法让我接近 但它似乎在微秒内丢失了尾随零 如果时间戳以非零数字结尾 则一
  • 从表中删除孤儿

    我正在尝试清理一张有很多孤立项目的桌子 我通过查找空值来检查是否与另一个表存在关系来解决此问题 DELETE FROM table1 LEFT JOIN table2 ON table1 ID table2 ID WHERE table2
  • 替换 Oracle 包的一部分

    我需要修改包内的一个过程 我需要接触声明和实施 由于我正在维护每次修改的补丁文件 因此我希望更改最小化 我可以仅使用更改的过程更新包 如果是 如何更新 还是需要提供完整的包定义和实现 您需要替换整个包规范和主体 您不能仅对包的一部分进行操作
  • 如何在 sqlalchemy 中创建基于文字的查询?

    我创建了一个函数来创建表达式 def test operator1 operation operator2 return literal column operator1 op operation operator2 现在当我用 test
  • 对于数据库来说,选择正确的数据类型会影响性能吗?

    如果是这样 为什么 我的意思是 tinyint 的搜索速度比 int 快吗 如果是这样 性能上的实际差异是什么 是的 根据数据类型 它确实有所不同 int vs tinyint不会在速度上产生明显的差异 但会在数据大小上产生差异 假设tin
  • 为什么这会返回资源 id #2? [复制]

    这个问题在这里已经有答案了 可能的重复 我如何从 PHP 中的 MySql 响应中 回显 资源 id 6 https stackoverflow com questions 4290108 how do i echo a resource
  • 将 UUID 存储为 base64 字符串

    我一直在尝试使用 UUID 作为数据库键 我希望占用尽可能少的字节数 同时仍然保持 UUID 表示形式的可读性 我认为我已经使用 base64 将其减少到 22 个字节 并删除了一些尾随的 这些 对于我的目的来说似乎没有必要存储 这种方法有
  • SQL 删除表并重新创建并保留数据

    在我们最初的设计中 我们搞砸了表中的外键约束 现在表已充满数据 我们无法在不删除表中所有记录的情况下更改它 我能想到的唯一解决方案是创建一个备份表并将所有记录放在那里 然后删除所有记录 更改表并开始将它们添加回来 还有其他 更好 的想法吗
  • 列中差异的数量

    我想检索一列每行中有多少个字母的差异 例如 如果您有一个值 test 而另一行有一个值 testing 则 test 和 testing 之间的差异为 4 个字母 该列的数据值为 4 I have reflected about it an
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 通过 Oracle 的数据库链接运行 SQL Server 存储过程

    参考如何通过数据库链接执行 Oracle 存储过程 https stackoverflow com questions 240788 how to execute an oracle stored procedure via a datab
  • 使用 where 进行 select 语句时,HSQLDB 用户缺乏权限或未找到对象错误

    我的数据库使用 SQuirrel SQL 客户端版本 3 5 3 和 HSQLDB 我已经能够为其指定相应的驱动程序 内存中 并创建一个别名 我创建了一个表 CREATE TABLE ENTRY NAME VARCHAR 100 NOT N
  • 如何从 PostgreSQL 中的时间戳列值提取一天中的时间(或小时)?

    我正在尝试从 PostgreSQL 中的 时间戳 列中提取一天中的时间 这是我的做法 但是 太糟糕了 知道如何做得更好吗 SELECT date part hour date demande text hours date part min
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int
  • 对多个数据库执行 SQL 查询

    我知道我的帖子与该论坛中的其他帖子的标题非常相似 但我真的找不到我需要的答案 这是我的问题 我的 Windows Server 上运行着 SQL Server 在我的 SQL Server 中 我有大约 30 个数据库 它们都具有相同的表和

随机推荐