文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MYSQL---字段的默认值

2023-09-30 09:48

关注

一、背景

        问题的原因也是十分简单,在csdn上随便百度就可以找到解决问题的方法,但为什么还要写这篇文章呢?因为在去尝试的时候自己遇到了一些有趣的问题,并且从中也学到了有意思的知识。

       报错: java.sql.SQLException: Field '表字段名' doesn't have a default value,这个错误的产生是使用java代码操作数据库的时候或者在Navicat里面(MYSQL客户端)执行sql语句时出错,mysql要求该字段必须指定一个默认值;

二、情景

        我模拟出来一个简单的情景,下面是数据库的表结构情况:

        我并不认为这样的表结构有什么问题,但进行添加操作(不给name指定值),会报错:Field 'name' doesn't have a default value ,‘name’和'address'后面相比较缺少了“DEFAULT NULL”(默认值),在此之前我认为就算‘name’不指定"DEFAULT NULL"(默认值)能达到的效果和'address'效果是一样的;

        解决方法也是多种多样的,要根据自己的实际业务需求去选择方法解决,解决方法我分为了指定字段默认值和不指定字段默认值两类解决方法。

三、解决

3.1 指定字段默认值

你可以通过下方sql语句来完成对表字段的默认值的设置:

ALTER TABLE '表名' ALTER COLUMN '表字段名' SET DEFAULT NULL;

设置完之后为确保没问题可以使用指令进行查看表结构是否调整(因为有时候像Navict刷新半天也没有更新到最新状态很烦):

show create table '表名';


3.2 不指定字段默认值

第一种:就是每次使用代码操作数据库之前为这个字段指定一个默认值;

第二种:

        MySQL 5.0.2 版本之后,默认情况下对于每个插入到表中的记录,如果未提供该表中的某列的值,则该列的值将会被设置为默认值,而不是空值或 NULL,那是因为MySQL 在版本 5.0.2 中引入了 STRICT_TRANS_TABLES 模式。

        这种模式提高了数据插入、更新和删除操作的严格性,确保在执行此类操作时不会引起数据不一致或冲突。

        在 STRICT_TRANS_TABLES 模式下,MySQL 使用更严格的事务模型来处理 INSERT、UPDATE 和 DELETE 查询,它执行原子性、一致性、隔离性和持久性这四个 ACID 属性。当执行 INSERT 或 UPDATE 操作时,如果数据不能插入或更新到数据表中,则该操作将被回滚,并返回错误信息。

        需要注意的是,使用 STRICT_TRANS_TABLES 模式可能会增加数据库操作的开销,对于大型数据集或高频率的写入操作可能会影响系统性能,因此需要谨慎使用。如果你不希望使用这种模式可以在 MySQL 的配置文件(my.cnf)中将 sql_mode 参数设置为其它模式。

另外,在 MySQL 5.7 版本后, STRICT_TRANS_TABLES 已经包含在 ONLY_FULL_GROUP_BY 模式中,这也是默认的 SQL 模式。如果您想在 MySQL 5.7 及以上版本中使用 STRICT_TRANS_TABLES 模式,则需要先关闭 ONLY_FULL_GROUP_BY 模式,然后启用 STRICT_TRANS_TABLES 模式。

        因此,要想在不指定默认值的情况下,依旧可以正常完成字段的插入操作,就需要将这个STRICT_TRANS_TABLES 模式从mysql的配置文件中剔除掉。

步骤一:现找到MySQL安装的位置

Windows安装的MySQL配置文件可以通过命令查找出来

-- 配置文件名称my.iniselect @@basedir;select @@datadir;

Linux:

MySQL 在 Linux 中的配置文件名为 my.cnf,它通常位于 /etc/mysql//etc/ 目录下。

步骤二:修改sql-mode配置,并重启MySQL

(1)windows重启 MySQL 服务

win+R组合键,弹出运行窗口, 输入  services.msc

(2)Linux 下重启 MySQL 服务

输入以下命令以停止 MySQL 服务:

-- 停止MySQL服务sudo systemctl stop mysql-- 开启MySQL服务sudo systemctl start mysql-- 重启MySQL服务sudo systemctl reload mysql

做完以上的操作之后,我们就可以实验了,不知道你们得出的是什么样的结果,欢迎评论区留言;

四、结论

发现使用MySQL客户端去添加已经没有问题了,但使用java代码连接数据库去操作,依旧还是报错,很烦;

 所以,我找来了一位大佬,在大佬的分析下,通过查看底层的代码,最终报错定位到

package com.mysql.cj.jdbc包下面的 ConnectionImpl 这个类里面setupServerForTruncationChecks()方法里面,其中jdbcCompliantTruncation的默认值为true,将Mysql JDBC Driver参数jdbcCompliantTruncation设置为false,即可运行成功,代码如下;
// 底层代码private void setupServerForTruncationChecks() throws SQLException {        synchronized (getConnectionMutex()) {            RuntimeProperty jdbcCompliantTruncation = this.propertySet.getProperty(PropertyKey.jdbcCompliantTruncation);            if (jdbcCompliantTruncation.getValue()) {                String currentSqlMode = this.session.getServerSession().getServerVariable("sql_mode");                boolean strictTransTablesIsSet = StringUtils.indexOfIgnoreCase(currentSqlMode, "STRICT_TRANS_TABLES") != -1;                if (currentSqlMode == null || currentSqlMode.length() == 0 || !strictTransTablesIsSet) {                    StringBuilder commandBuf = new StringBuilder("SET sql_mode='");                    if (currentSqlMode != null && currentSqlMode.length() > 0) {                        commandBuf.append(currentSqlMode);                        commandBuf.append(",");                    }                    commandBuf.append("STRICT_TRANS_TABLES'");                    this.session.execSQL(null, commandBuf.toString(), -1, null, false, this.nullStatementResultSetFactory, null, false);                    jdbcCompliantTruncation.setValue(false); // server's handling this for us now                } else if (strictTransTablesIsSet) {                    // We didn't set it, but someone did, so we piggy back on it                    jdbcCompliantTruncation.setValue(false); // server's handling this for us now                }            }        }    }
在yaml文件中添加上&jdbcCompliantTruncation=false,便可添加成功;spring:  datasource:    url: jdbc:mysql://localhost:3306/demo_03?useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8&jdbcCompliantTruncation=false    username: root    password: root    driver-class-name: com.mysql.cj.jdbc.Driver

OK

来源地址:https://blog.csdn.net/m0_71074676/article/details/130463009

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯