IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 【已解决】Error querying database. Cause: java.sql.SQLDataException: ORA-01861: 文字与格式字符串不匹配 -> 正文阅读

[大数据]【已解决】Error querying database. Cause: java.sql.SQLDataException: ORA-01861: 文字与格式字符串不匹配

🎉在工作场景中遇到这样一个需求,需要统计指定时间段内网站的访客数据。例如,统计从 2022 年 4 月 1 号至 2022 年 4 月 30 号内网站的所有访客记录,之后生成一个统计报表。需要注意的是,这里的时间范围是指从 2022 年 4 月 1 号凌晨 0 点 0 分 0 秒 至 2022 年 4 月 30 号 23 点 59 分 59 秒,单位必须精确到秒!

🎉对于这样的一个需求,解决思路其实很简单,无非就是对后台数据库进行时间范围的查询操作,编写 SQL 语句代码,肯定要用到 between and. 然而这里有一个细节需要注意,就是在 Oracle 数据库中,虽然 between and包含端点值的,但是在 Oracle 数据库中使用 to_date 函数对字符串进行转换时,默认的时间筛选是从当天的 00:00:00 开始计算的。也就是说,如果想要查询 2022-04-01 至 2022-04-02 的数据,使用日期函数 to_date 转换时,筛选的是 2022-04-01 00:00:00 至 2022-04-02 00:00:00 的数据,它是不包含 2022-04-02 这天的数据的

🎉为了解决这个问题,通常的做法是对于查询的结束日期采取加1的操作,这样自然就包含了结束日期当天的数据了。在我所负责维护的这个项目中,前任维护者也是采取了这样的方法,但是在后期应用于生产环境中,出现这样的问题。当指定的时间范围包含了每个月最后一天时,统计数据便出现了 bug. 反馈到我这边之后,我通过查询后台错误日志,定位到这样的错误提示:

org.springframework.dao.DataIntegrityViolationException: 
### Error querying database.  Cause: java.sql.SQLDataException: ORA-01861: 文字与格式字符串不匹配

🎉错误日志提示指出,在执行 SQL 查询时,出现 文字与格式字符串不匹配错误。于是,我便又去扒出后端 SQL 语句编写的代码,下面是出错的代码位置

where ADDTIME between to_date(#{beg}, 'yyyy-mm-dd hh24:mi:ss') and to_date(#{end}+1, 'yyyy-mm-dd hh24:mi:ss')

🎉注意到 to_date(#{end}+1 这句代码,end 表示传入的时间字符串,它是形如如 20220430 这样的字符串格式,{end}+1 是为了查询出 20220430 当天的数据。但是,仔细想一下当 20220430+1 此时不就是 20220431 了吗?但是四月不可能有 31 号的,因此联想到每次查询每个月最后一天的数据时总是报错的问题,也就找到了问题的根源了!

🎉因此,{end}+1 这样的操作时不能再继续使用了,必须删掉 +1 这个问题根源。那么,删掉 +1 之后,还能查询出边界日期的当天数据吗?在经过一番了解之后,可以通过修改 Oracle 中 to_date 函数的默认筛选时间的方式解决,可以将默认筛选时间指定为 23:59:59,这样便可以查询出边界日期的当天数据了。

?后台业务逻辑代码修改为

List<ReportMobileVO> pvList = userLoginMapper.getPV2(beg, end + " 23:59:59");

?后台 SQL 代码修改为

where ADDTIME between to_date(#{beg}, 'yyyy-mm-dd hh24:mi:ss') and to_date(#{end}, 'yyyy-mm-dd hh24:mi:ss')

🎉这里的 end 表示边界日期,在调用接口方法执行 SQL 查询之前,传入的 end 参数拼接字符串 23:59:59,这样可以指定筛选时间。例如,指定之后的筛选时间为 20220430 23:59:59,这样既可以将边界日期当天数据包含在内,又不会出错了,问题得到解决!

🚨最后,需要说明的是,如果错误原因并不是上述所描述的情况,则应该重点仔细检查传入的时间字符串格式。例如,传入的参数是不是形如 20220401这样的格式,如果不是的话,是不能被解析的

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 11:58:25  更:2022-05-10 12:00:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:56:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码