背景

今日做开发,数据库使用了SQLServer,expiredTime的值为null时更新报错了,其字段类型为datetime2:

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 不允许从数据类型 varbinary 到 datetime2 的隐式转换。请使用 CONVERT 函数来运行此查询。

解决方案

目前发现两种解决方案,这两种方法都是类似的。

方法一 指定mapping

不用写JdbcType.,直接写枚举的名称,比如TIMESTAMP

lambdaUpdate()
.eq(ShortLink::getId, id)
.set(ShortLink::getExpiredTime, req.getExpiredTime(), "jdbcType=TIMESTAMP")
.set(ShortLink::getStatus, req.getStatus())
.update();

方法二 在XML里写jdbcType

<update id="updateData">
UPDATE table
SET
ExpiredTime = #{req.expiredTime,jdbcType=TIMESTAMP}
WHERE Id = #{id}
</update>

还有一种方法就是把数据库的字段类型设置成datetime,这样更新就不会报错。

网上说的TableField注解里加jdbcType或者typeHandler是没用的,这两个只对查询后的结果有效。

根本原因

根本原因是在更新数据时,因为值为null,jdbcType被自动设置为了JdbcType.OTHER,同时可能因为SQLServer的datetime2没有做自动转换,导致报错。

我们都知道,执行SQL会使用PreparedStatement,然后通过set设置参数的值。

SQLServer的驱动有它自己的PreparedStatement,SQLServerPreparedStatement

在SQLServerPreparedStatement的setNull方法里打一个断点,就能看到jdbcType的值是1111,对应就是JdbcType.OTHER

public final void setNull(int index, int jdbcType) throws SQLServerException {
if (loggerExternal.isLoggable(java.util.logging.Level.FINER))
loggerExternal.entering(getClassNameLogging(), "setNull", new Object[] {index, jdbcType});
checkClosed();
setObject(setterGetParam(index), null, JavaType.OBJECT, JDBCType.of(jdbcType), null, null, false, index, null);
loggerExternal.exiting(getClassNameLogging(), "setNull");
}

那这个jdbcType又来自哪?来自DefaultParameterHandler

这里可以通过配置来改变jdbcTypeForNull的值,配置成TIMESTAMP是可以的,但是可能对其他字段有影响,不推荐,配置成NULL一样的问题。(如果要配置成NULL不要写成小写的null,否则真的会是null,或者外面加双引号)

mybatis-plus:
configuration:
jdbc-type-for-null: TIMESTAMP

上面是jdbcType和值都为null的情况,一番DEBUG后发现,jdbcType的值来自于parameterMappings

SqlSourceBuilder.ParameterMappingTokenHandler.buildParameterMapping(String content)方法。

这个方法会解析传入的content,也就是#{}中间的值,然后根据值去设置jdbcType等属性。

这里可以看到,并没有指定jdbcType。

如果指定了,值会是这样的:

有没有办法加上jdbcType呢?查看mybatis-plus的源码,发现需要传入一个叫mapping的参数。

默认情况下mapping会是null。

MybatisPlus更新null到datetime2字段报错:不允许从数据类型 varbinary 到 datetime2 的隐式转换的更多相关文章

  1. sql server中NULL导入decimal字段时报错

    sql server中NULL导入decimal字段时报错 在导入CSV文件时,如果decimal字段为null值,导致文本文件入库时失败. 错误现象 构造例子 新建一张表,包含decimal字段. ...

  2. mysql中大数据表alter增加字段报错:"1034 Incorrect key file for table 'table_name'; try to repair it"

    mysql中大数据表alter增加字段报错:"1034 Incorrect key file for table 'table_name'; try to repair it" 现 ...

  3. 多表更新时碰到的 ERROR 1292 (22007)隐式转换错误

    表结构如下: Create Table: CREATE TABLE `test_t2` ( `id` int(11) NOT NULL AUTO_INCREMENT, `customer_no` va ...

  4. 工作总结 无法确定条件表达式的类型,因为“<null>”和“System.DateTime”之间没有隐式转换 解决办法 object——Nullable<T> (可空类型)

    可空值类型 备注     一种类型认为是可以为 null,如果它可以分配一个值,也可以分配null,这意味着类型具有无论如何没有值. 默认情况下,所有都引用类型,如String,是否可以为 null, ...

  5. 无法确定条件表达式的类型,因为“<null>”和“System.DateTime”之间没有隐式转换----解决办法

    例子:(报错了) public DateTime? time { get; set; } time = item.HospOutDate.HasValue ? DateTime.Parse(item. ...

  6. null的坑 和 比较运算符、相等运算符的隐式转换问题 (在javascript中,null>=0 为真,null<=0 为真,null==0却为假,null到底是什么?)

    null在关系运算中的坑 & 关系运算符的隐式转换问题 注意: 比较运算符 和 相等运算符 的 ECMAscript 语法实现不同. 比较运算符 和 相等运算符 对数据进行了隐式转换, 相当于 ...

  7. mongodb增加新字段报错解决方法

    今天想在项目的一个集合里增加一个新字段 db.article.update({},{$set:{status:0}},{multi:true}) multi : 可选,mongodb 默认是false ...

  8. django在model中添加字段报错

    在以下类中添加 description 字段后, class Colors(models.Model): colors = models.CharField(u'颜色', max_length=10) ...

  9. Mysql 升级到 5.6 后插入语句时间字段报错:Incorrect datetime value: '' for column 'createtime'

    今天部署服务器项目运行,当遇见有时间数据对象的插入和更新操作的时候,就报错,如下: Caused by: com.mysql.jdbc.MysqlDataTruncation: Data trunca ...

  10. kali linux 2.0配置更新源后apt-get update 报错

    这个是我/etc/apt/sources.list的更新源: deb http://http.kali.org/kali kali-rolling main contrib non-free deb ...

随机推荐

  1. 一条 SQL 语句在 MySQL 中的执行过程

    一条 SQL 语句在 MySQL 中的执行过程 当一条 SQL 语句被提交到 MySQL 时,它会经历多个步骤,包括解析.优化.执行等.以下以 SELECT 语句为例,详细描述整个执行流程. 1. 客 ...

  2. Java编程--观察者(Observer)设计模式

    观察者设计模式 观察者设计模式是一种行为设计模式,允许对象在其状态改变时通知其他依赖对象.它创建了一种发布者(Subject)和订阅者(Observer)之间的依赖关系.这种模式经常用于实现事件处理系 ...

  3. Oracle 使用UTL_HTTP发送http请求--转载

    参考:https://blog.csdn.net/tmaczt/article/details/82665885 GET方式 CREATE OR REPLACE FUNCTION FN_HTTP_GE ...

  4. <HarmonyOS第一课09>应用程序框架进阶#鸿蒙课程##鸿蒙生态#

    课程介绍 本课程<应用程序框架进阶>旨在深入探讨应用程序框架的核心概念和高级特性.课程首先介绍应用程序框架的基本概念,确保学员对框架有全面的认识.接着,我们将深入探讨AbilityStag ...

  5. 信息资源管理综合题之“S公司规划网络系统-内部用户需要使用的信息安全技术及其相应用途”

    一.案例:S公司是某网络设备制造商在国内的一级代理商,总部设在上海,在外高桥有一处大型的仓库,其二级经销商客户分布在全国几十座大中城市,并在北京.成都.西安和沈阳等地设立了办事处.总部实施了ERP系统 ...

  6. 你了解ConcurrentHashMap吗?ConcurrentHashMap九连问

    多线程环境下,使用Hashmap进行put操作会造成数据覆盖,应该使用支持多线程的 ConcurrentHashMap. HashMap为什么线程不安全 put的不安全 由于多线程对HashMap进行 ...

  7. windows系统应急

    Windows系统的应急响应主要关注在发生安全事件或攻击后,如何迅速采取措施恢复系统的正常运行并确保数据的安全性.应急响应的目标是减少系统受到攻击的损害.恢复操作以及防止类似事件的再次发生. 应急响应 ...

  8. SAP 发布简易REST 一:login验证

    说明:这里没有使用ODATA,只是用最基础的HTTP和JSON来处理. 这篇为第一篇,所以这里来说说验证的一些东西. 创建SE24实施类,做http接口:ZCRM_REST 激活后,添加接口类:IF_ ...

  9. ArkUI-X跨平台技术落地-华为运动健康(二)

    原生和ArkUI界面参数传递 在原生页面拉起对应的跨平台的页面时,会将代表拉起哪个页面的参数通过intent的形式传递给跨平台的Entry模块,这里主要用到的是intent的putExtra()方法进 ...

  10. 开源交流丨批流一体数据集成框架ChunJun数据传输模块详解分享

    课件获取:关注公众号"ChunJun",后台私信 "课件" 获得直播课件 视频回放:点击这里 ChengYing开源项目地址:github 丨 gitee 喜欢 ...