背景

今日做开发,数据库使用了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. 【解决方法】edge浏览器不小心删除收藏夹怎么办?

    C:\Users\用户名\AppData\Local\Microsoft\Edge\User Data\Default 进入该目录,找到名为Bookmarks或Bookmarks.bak或Bookma ...

  2. wpf 控件绑定鼠标命令、键盘命令

    1 <Window x:Class="CommandDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/w ...

  3. 微信小程序 6/12 的坑

    配置 小程序的时候配置请求的是 https://xxx 不是http://xxx 前端请求的链接都是https

  4. 『Plotly实战指南』--在金融数据可视化中的应用(上)

    在当今复杂多变的金融市场中,金融数据分析的重要性不言而喻. 无论是投资者.金融机构还是研究人员,都需要通过对海量金融数据的分析来洞察市场趋势.评估风险并做出明智的决策. 据彭博社统计,专业投资者平均需 ...

  5. 探索Rust:所有权和借用的魅力与应用

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  6. QuickSort之C#实现

    /// <summary> /// 快速排序中的切分 /// lIndex已经是基准值,i记录基准值的大小值的边界,j记录目前遍历的边界: /// i值必须从lIndex+1开始,因为基准 ...

  7. Special Binary String——LeetCode进阶路

    原题链接https://leetcode.com/problems/special-binary-string/ 题目描述 Special binary strings are binary stri ...

  8. Evaluate Division——LeetCode进阶路

    原题链接https://leetcode.com/problems/evaluate-division/ 题目描述 Equations are given in the format A / B = ...

  9. 利用 SSE 实现流式 AI 聊天交互(三)

    在 AI 赋能的时代,即时交互式对话体验成为众多应用的核心功能之一.本文将介绍如何使用 流式 SSE (Server-Sent Events) 技术,实现高效的 AI 聊天交互,提供更加丝滑的用户体验 ...

  10. 2023人形全能赛openmv巡线代码

    openmv import sensor, image, time, math from pyb import LED, millis, UART class RobotControl: flag = ...