问题描述
在 OceanBase 数据库中,对一个已存在的表执行 ALTER TABLE 语句,尝试降低字段长度时,可能会遇到失败的情况。具体表现为返回错误码 1441,SQL 状态为 HY000,错误信息。
ErrorCode = 1441, SQLState = HY000, Details = ORA-01441: cannot decrease column length because some value is too big
示例如下。
创建测试表。
obclient > CREATE TABLE TESTBAI3 ("IDE" VARCHAR2(5 char)); Query OK, 0 rows affected (0.080 sec)增加 varchar2 长度。
obclient > ALTER TABLE "TESTBAI3" MODIFY ("IDE" VARCHAR2(10 char)); Query OK, 0 rows affected (0.050 sec)插入测试数据。
obclient > INSERT INTO TESTBAI3 ("IDE") VALUES ('一二三四五六七八九十'); Query OK, 1 row affected (0.021 sec)obclient > INSERT INTO TESTBAI3 ("IDE") VALUES ('一二三四五六七八九1'); Query OK, 1 row affected (0.001 sec)obclient > INSERT INTO TESTBAI3 ("IDE") VALUES ('一二三四五六七八九十1'); ErrorCode = 12899, SQLState = 22001, Details = ORA-12899: value too large for column "SYS"."TESTBAL3"."IDE" (actual: 31, maximum: 10)提交插入数据。
obclient > commit;尝试缩短列长度。
obclient > ALTER TABLE "TESTBAI3" MODIFY ("IDE" VARCHAR2(30 byte)); ErrorCode = 1441, SQLState = HY000, Details = ORA-01441: cannot decrease column length because some value is too bigobclient > ALTER TABLE "TESTBAI3" MODIFY ("IDE" VARCHAR2(39 byte)); ErrorCode = 1441, SQLState = HY000, Details = ORA-01441: cannot decrease column length because some value is too big
适用版本
OceanBase 数据库 V2.x 和 V3.x 版本。
问题原因
由于在修改字段长度时,字段中已经存在的值的长度超过了新的长度限制。在 UTF8 编码中,一个字符的范围是 1-4 字节,因此 "10 char" 最多可以占用 40 个字节的存储空间。ALTER TABLE 修改字段长度是根据定义长度来判断是否允许修改字段,而不是根据数据实际最大的长度。
解决方法
需要确保修改的字段长度大于等于已有数据的实际最大长度。在这种情况下,可以考虑将 "IDE" 字段的长度从 10 修改为大于等于 40(或更大),以适应已有数据的长度。
下面是修改字段长度的示例 ALTER TABLE 语句。
obclient > ALTER TABLE "TESTBAI3" MODIFY ("IDE" VARCHAR2(40 BYTE));
Query OK, 0 rows affected (0.021 sec)
注意
在执行任何表结构修改之前,请务必备份重要的数据,并确保您已经充分了解并评估了修改操作的风险和影响。