数据库字段超长,不同版本截取和报错问题+字段存储限制问题

文章讲述了MySQL中varchar类型字段遇到超出长度时的行为,取决于数据库的严格模式设置:严格模式下报错,非严格模式下自动截取。讨论了不同字符编码对存储数量的影响以及如何根据业务场景选择适当的设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mysql的varchar类型的字段,如果插入的数据超过设定的length,就会有问题,通常会有2种情况,第一种是报错,第二种是直接自动截取,那什么情况下会直接报错,什么情况下会自动截取呢?

答案是和数据库是否设置了严格模式有关

一.直接报错
我们先来看第一种情况,test_varchar长度是8,当我们通过客户端加长字符串时,会提示Maximum text length is set to 8.,顾名思义,就是字段超长了,不能再加了

 那我们再通过直接insert语句来插入长度超过8的:

INSERT INTO `test123` (`text_varchar`) VALUES ('123456789---');
发现直接提示:Data too long for column 'text_varchar' at row 1

那如果是代码里调用,也会直接抛出这个异常

既然说了是否报错是取决于数据库是否设置了严格模式,我们来看看当前数据库的严格模式设置:
执行:select @@sql_mode,发现返回值如下:ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

当返回值包含STRICT_TRANS_TABLES(存储引擎启用严格模式,非法数据值被拒绝)时,表示开启了严格模式,此时如果字段超长会直接报错

二.自动截取
我们将数据库模式改成非严格模式,即把sql_mode中的STRICT_TRANS_TABLES去掉:

SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

执行完之后重启客户端,再select @@sql_mode就发现STRICT_TRANS_TABLES已经没有了

我们再来进行操作,首先在客户端直接加,还是一样的提示Maximum text length is set to 8.

我们再来用insert语句来执行:

INSERT INTO `test123` (`text_varchar`) VALUES ('123456789---');

可以发现此时并没有报错并且插入成功了: 

 但是插入成功的数据被自动截取了,值还是12345678,超长的部分被截取掉了

三.总结
1.当varchar类型超长,数据库选择报错还是自动截取取决于是否设置严格模式,严格则会报错

2.实际业务场景中,按需选择,谨慎选择因为设置sql_mode是按照数据库的,不是单表的,可能会影响到其他的表

3.个人建议开启严格模式,因为这样当数据超长时能及时报错发现问题并且进行扩展字段长度,限制提交字段长度等策略,如果非严格,则会被截取,如果是不重要的字段,可能很久之后才发现字段值缺失(被截取了),也无法找回,就造成了数据丢失,最终还是看各自的业务场景

                        
原文链接:数据库字段超长为什么有时候报错,有时候自动截取_mysql超出字段长度报错-优快云博客

 

mysql中varchar字段能存多少汉字
4.0版本以下,varchar(100),指的是100字节,如果存放UTF8汉字时,只能存33个(每个汉字3字节)

5.0版本以上,varchar(100),指的是100字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放100个。

UTF8编码中一个汉字(数字也算汉字)占用3个字节

GBK编码中一个汉字(数字也算汉字)占用2个字节

Mysql记录行数据是有限的。大小为64k,即65535个字节

而varchar要用1-2字节来存储字段长度,小于255的1字节,大于255的2字节。

所以

当编码形式为utf8时varchar最大可以存( 65535字节-2字节 )/3字节=21844字符余1 大概21844个汉字,也就是说可以设置的最大长度为21844

当编码形式为GBK时varchar最大可以存(65535字节-2字节)/2字节=32766字符余1 大概32766个汉字,也就是说可以设置的最大长度为32766

mysql中varchar字段能存多少汉字_mysqlvarchar100能存多少汉字-优快云博客

### 正确使用 TRUNC TO_CHAR 函数 在 SQL 中,`TRUNC` 函数用于截断日期时间值到指定的精度单位,默认情况下会将其截断至当天的午夜(即 00:00:00)。而 `TO_CHAR` 函数则可以将日期转换为字符串形式,并按照给定的格式模型进行显示。 为了正确地组合使用这两个函数并按 `'yyyy-mm-dd'` 的格式处理日期时间字段 `EGETIME`,可以通过以下方式实现: #### 解决方案 以下是具体的 SQL 查询语句及其解释: ```sql SELECT TO_CHAR(TRUNC(EGETIME), 'yyyy-mm-dd') AS formatted_date FROM your_table; ``` - 使用 `TRUNC(EGETIME)` 将日期时间字段 `EGETIME` 截断至当天的午夜[^1]。 - 接着通过 `TO_CHAR(..., 'yyyy-mm-dd')` 将截断后的日期转换为字符串,并采用 `'yyyy-mm-dd'` 格式输出[^2]。 此方法能够有效避免因时间部分导致的错误,同时确保最终结果仅保留日期部分且符合所需的格式。 --- ### 注意事项 如果目标数据库中的 `EGETIME` 是一个字符型数据而非真正的日期类型,则需要先将其转换为日期再执行上述操作。例如: ```sql SELECT TO_CHAR(TRUNC(TO_DATE(EGETIME, 'YYYY-MM-DD HH24:MI:SS')), 'yyyy-mm-dd') AS formatted_date FROM your_table; ``` 这里利用了 `TO_DATE` 函数将字符串类型的 `EGETIME` 转换成了日期类型[^5]。 另外,在某些特定场景下可能还需要考虑时区的影响。比如当源时间为 UTC 时间戳但需展示为本地时间时,可借助 `NEW_TIME` 或者其他与时区相关的函数调整后再做进一步处理[^4]。 --- ### 示例验证 假设表 `your_table` 存储了一列名为 `EGETIME` 的数据如下所示: | EGETIME | |----------------------| | 2023-10-27 15:30:45 | 运行查询后得到的结果将是: | FORMATTED_DATE | |---------------------| | 2023-10-27 | 这表明原始的时间已被成功截取成纯日期格式[^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值