java - 使 oracle last_day 函数在 oracle 和 h2 之间兼容
问题描述
我在 java 项目中有一个 sql 查询。它必须在 oracle 和 h2 中执行,具体取决于客户端和 DBMS 选举。
它必须返回 sent_date 是 Month 减一的值(上个月的注册表)
SELECT * FROM TABLE WHERE SENT_DATE BETWEEN ADD_MONTHS(TRUNC(SYSDATE,'mm'),-1)
AND LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE,'mm'),-1)) ORDER BY ELAPSED_TIME DESC
问题是,LAST_DAY 函数是 Oracle 特定的函数,在 H2 中不存在,H2 日期管理有时在 Oracle 中不起作用,但我需要它完全兼容。之前有一个问题Make Oracle last_day function be compatible with H2 database但答案集中在测试不佳的系统上,而不是正确的解决方案上。
我们怎样才能做到这一点?
解决方案
它可能会更快乐:
SELECT * FROM TABLE
WHERE SENT_DATE BETWEEN ADD_MONTHS(TRUNC(SYSDATE,'mm'),-1) AND TRUNC(SYSDATE,'mm') - 1
ORDER BY ELAPSED_TIME DESC
表明它们评估为相同的值:
SELECT ADD_MONTHS(TRUNC(SYSDATE,'mm'),-1) as orig_start,
LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE,'mm'),-1)) as orig_end,
TRUNC(SYSDATE,'mm') - 1 as new_end
FROM dual;
ORIG_START ORIG_END NEW_END
------------------- ------------------- -------------------
2019-08-01 00:00:00 2019-08-31 00:00:00 2019-08-31 00:00:00
但请记住,这between
是包容性的,因此如果您sent_date
有非午夜时间,则将排除从 2019-08-31 00:00:01 到 2019-08-31 23:59:59 的任何时间。
这样做更安全:
SELECT * FROM TABLE
WHERE SENT_DATE >= ADD_MONTHS(TRUNC(SYSDATE,'mm'),-1)
AND SENT_DATE < TRUNC(SYSDATE,'mm')
ORDER BY ELAPSED_TIME DESC
这将包括 2019-08-01 00:00:00 或之后的所有内容,直到(但不包括)2019-09-01 00:00:00 - 这样就不会出现丢失的日期。
或者,如果它不能识别add_months
:
SELECT * FROM TABLE
WHERE SENT_DATE >= TRUNC(SYSDATE,'mm') - INTERVAL '1' MONTH
AND SENT_DATE < TRUNC(SYSDATE,'mm')
ORDER BY ELAPSED_TIME DESC
(我无法测试这些中的任何一个是否真的在 H2 中工作...... *8-)
推荐阅读
- git - Gitlab 生成变更日志脚本
- inverse - 评估函数的逆
- sesam - Sesam DTL - 检查字符串是否由字母组成
- javascript - 使用 DefineProperty 在原型链中添加属性
- c# - 在异步线程中分配对象?
- python - cmd 如何比 python idle 工作得更快(比如 10 倍)?
- azure - 使用 .NET Core SDK 创建筛选的服务总线订阅
- c# - 在 Web API 中上传单个文件
- angular - 如何从Angular中的Api获取数据到组件中的数组
- sql-server - Microsoft SQL Server - 谁创建了跟踪?