oracle中date类型在mybatis中查询时遇到的坑

背景

最近生产遇到个问题,大致也是遵从墨菲定律吧,你感觉会出问题的地方,可能就真会出问题。oracle我一直觉得过于复杂,从来没有系统学习过。最近遇到的问题就和date这种类型的列有关系,有个表中的记录大概这样:2024-05-13 00:00:00.000 ,然后类型是date,我还以为这种类型只包含年月日,结果发现其包含了7个字段:世纪、年、月、日、时、分、秒。另外,我还以为这个类型和时区有关系,结果经过这两天的补课,发现这个类型是不包含任何的时区信息的。

简单说下遇到的问题吧,oracle里有一个考勤结果表,主要包含了oa账号、date、考勤结果,之前是有一个数据库定时任务,每天早上6点会调用一个存储过程,存储过程里会往这个表里插入数据。

由于不好调试,且这个存储过程有点bug,我就用xxljob+java重新实现了一下,初版是ai写的,我自己调整了部分代码。

我的java实现大概如下:

为了支持幂等(xxljob重复运行),会检查某个用户在某一天是否已经有记录了,有记录就先删掉,没记录就插入(典型的先删再加)。

结果不记得当时是本地测试不充分还是怎么的,反正就上线了,上线后,xxljob一跑,结果发现存储过程那边写入的记录没删掉,然后重新插入了一条一样的,导致同一个用户同一天有了多条记录,导致app侧报错。

问题代码

数据库表

我们有个这个表:T_ATTENDANCE_RESULT_DAY

核心字段我精简下:

shell 复制代码
"OA_ACCOUNT" VARCHAR2(20),  oa账号
"TERM" DATE类型, 考勤日期

原存储过程写入的数据如下:

sql 复制代码
SELECT tard.OA_ACCOUNT ,term FROM T_ATTENDANCE_RESULT_DAY tard WHERE tard.OA_ACCOUNT = 'zhangsan' AND tard.TERM = DATE '2026-09-13'

OA_ACCOUNT|TERM                   |
----------+-----------------------+
zhangsan  |2026-09-13 00:00:00.000|

mybatis

注意啊,下面我传的是个LocalDate:

java 复制代码
int deleteByBusinessKey(@Param("oaAccount") String oaAccount,
                        @Param("term") LocalDate term);

下面sql中,term的jdbcType是TIMESTAMP:

xml 复制代码
<delete id="deleteByBusinessKey">
    delete from t_attendance_result_day
     where oa_account = #{oaAccount,jdbcType=VARCHAR}
       and term = #{term,jdbcType=TIMESTAMP}
</delete>

传值:

java 复制代码
@PostMapping(path = "/testDelete")
@DS("attendance")
@Operation(summary = "testDelete", tags = "考勤结果分析处理")
public Message<TAttendanceResultDay> testDelete() {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate localDate = LocalDate.parse("2026-09-13", formatter);
    int i = tAttendanceResultDayMapper.deleteByBusinessKey("zhangsan", localDate);
    System.out.println(i);

    return successResponse();
}

再交代下服务器端oracle版本:

sql 复制代码
SELECT * FROM v$version;
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

java这边的版本:

xml 复制代码
spring boot 2.7.16 
jdk8
<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc8</artifactId>
    <version>23.2.0.0</version>
    <scope>compile</scope>
</dependency>

调这个接口试试:

xml 复制代码
09-13 13:19:33.621 [http-nio-8085-exec-7] DEBUG [42c6843bd13e4a3b] c.h.p.m.T.deleteByBusinessKey ==>  Preparing: delete from t_attendance_result_day where oa_account = ? and term = ? [BaseJdbcLogger.java:137]
09-13 13:19:38.440 [http-nio-8085-exec-7] DEBUG [42c6843bd13e4a3b] c.h.p.m.T.deleteByBusinessKey ==> Parameters: zhangsan(String), 2026-09-13(LocalDate) [BaseJdbcLogger.java:137]
09-13 13:19:38.454 [http-nio-8085-exec-7] DEBUG [42c6843bd13e4a3b] c.h.p.m.T.deleteByBusinessKey <==    Updates: 0 [BaseJdbcLogger.java:137]

可以发现,影响的行为0行,没删掉。

原因分析

抓包

我其实先抓了个网络包,发现看不到东西,date这种类型的参数,可能不是字符串,所以看不到:

debug

我发现,设置参数主要在这个部分:org.apache.ibatis.executor.SimpleExecutor#doUpdate

这个ParameterHandler是个接口,就包含两方法:

java 复制代码
public interface ParameterHandler {

  Object getParameterObject();

  void setParameters(PreparedStatement ps) throws SQLException;

}

我的项目里就两个实现:

一个是mybatis包里的org.apache.ibatis.scripting.defaults.DefaultParameterHandler

另一个是mybatis-plus里的:com.baomidou.mybatisplus.core.MybatisParameterHandler

我这边走的是mybatis-plus。

方法的实现,主要就是获取sql中,看看需要绑定的参数列表,然后遍历,最终调用preparedStatement中的各种set方法去设置值。

在设置值之前,需要先根据参数的class(如"zhansgan"的class是java.lang.String)和xml中指定的jdbcType,来找到一个handler:

比如上图找到的是StringTypeHandler。然后开始调用handler的方法:

shell 复制代码
handler.setParameter(ps, i, parameter, jdbcType);

org.apache.ibatis.type.StringTypeHandler这个handler中,设置值,就是调用java.sql.PreparedStatement#setString

最终就会调用到下面oracle驱动的部分:

检查term参数是如何被设置

根据参数类型(LocalDate)和jdbcType(TIMESTAMP),最终的handler为:

org.apache.ibatis.type.LocalDateTypeHandler

这个handler中是调用preparedStatement的setObject方法来设置参数的:

oracle驱动部分

oracle中的setObject方法也是继续调用底层oracle.jdbc.driver.T4CPreparedStatement的setObject方法

然后根据LocalDate类型计算了一个sqlType为93:

这边会把LocalDate转成oracle自己的一个oracle.sql.TIMESTAMP类型:

转换器代码如下:

java 复制代码
        CONVERTERS.put(new Key(LocalDate.class, TIMESTAMP.class), new JavaToJavaConverter<LocalDate, TIMESTAMP>() {
            protected TIMESTAMP convert(LocalDate src, OracleConnection conn, Object srcExtra, Object targetExtra) throws Exception {
                return new TIMESTAMP(src); --就是这里
            }
        });
java 复制代码
public TIMESTAMP(LocalDate ld) {
    super(toBytes(ld));
}
public static byte[] toBytes(LocalDate ld) {
    return ld == null ? null : toBytes(ld.atTime(12, 0, 0)); -- 这里,把传入的LocalDate设置了中午12点!
}

找到问题了,虽然传入的是日期2026-09-13,实际最终变成了:

shell 复制代码
2026-09-13 12:00:00

那当然是删不掉了。

另外,这里会把这个日期,转换成byte数组:

如2026年,result0就是2026/100 + 100 = 120,result1就是2026%100 + 100,就是126:

其实拿这个16进制数组,可以去wireshark的抓包中找到对应的数据了:

如何修改

那找到问题了,接下来就修改一下,看起来是传入了LocalDate导致的问题,那我们mapper这里传LocalDateTime吧。

java 复制代码
<delete id="deleteByBusinessKey">
    delete from t_attendance_result_day
     where oa_account = #{oaAccount,jdbcType=VARCHAR}
       and term = #{term,jdbcType=TIMESTAMP}
</delete>

        
int deleteByBusinessKey(@Param("oaAccount") String oaAccount,
                            @Param("term") LocalDateTime term);


@PostMapping(path = "/testDelete")
@DS("attendance")
@Operation(summary = "testDelete", tags = "考勤结果分析处理")
public Message<TAttendanceResultDay> testDelete() {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate localDate = LocalDate.parse("2026-09-13", formatter);
    LocalDateTime localDateTime = localDate.atStartOfDay();
    int i = tAttendanceResultDayMapper.deleteByBusinessKey("zhangsan", localDateTime);
    System.out.println(i);

    return successResponse();
}

修改后,重新观察,发现最终在oracle中还是会转换,这次是从LocalDateTime转TIMESTAMP:

现在看着传的没问题了:

结果:

java 复制代码
09-13 14:12:46.288 [oaxdb housekeeper] WARN  [] com.zaxxer.hikari.pool.HikariPool oaxdb - Thread starvation or clock leap detected (housekeeper delta=50s394ms603µs500ns). [HikariPool.java:788]
09-13 14:12:46.289 [http-nio-8085-exec-1] DEBUG [dbbc18a0db9b4972] c.h.p.m.T.deleteByBusinessKey ==> Parameters: zhangsan(String), 2026-09-13T00:00(LocalDateTime) [BaseJdbcLogger.java:137]
09-13 14:12:46.305 [http-nio-8085-exec-1] DEBUG [dbbc18a0db9b4972] c.h.p.m.T.deleteByBusinessKey <==    Updates: 0 [BaseJdbcLogger.java:137]

还是没删除掉!

后面又简单尝试了下别的,还是没解决,只能让ai帮我看了。

ai救场

把这个问题的上下文丢给了ai,我的是glm 5.3,吭哧吭哧干了十几分钟,出结果了。

我好好学习了下它的思路,另外,也感叹下,现在真就是干不过ai了。

ai从我的代码库里找到了数据库连接,账号密码啥的,自己写了个java类,把问题给复现了。

复现后,使用了一个dump函数查看发到数据库服务器端的数据到底是啥。

sql 复制代码
比如下面的sql,dump(term)就可以查看到oracle中该字段的实际内容:
SELECT dump(term),term FROM T_ATTENDANCE_RESULT_DAY tard WHERE tard.OA_ACCOUNT = 'zhangsan' AND tard.TERM = DATE '2026-09-13'

DUMP(TERM)                      |TERM                   |
--------------------------------+-----------------------+
Typ=12 Len=7: 120,126,9,13,1,1,1|2026-09-13 00:00:00.000|

可以看到,这列在数据库侧的实际存储字节是:Typ=12 Len=7: 120,126,9,13,1,1,1

那么,我们这边的mybatis中调用oracle驱动,最终传给数据库服务器的是啥呢?

xml 复制代码
    <select id="selectDump" resultType="java.lang.String">
        select dump(#{term,jdbcType=TIMESTAMP})   as termDump  from dual
    </select>
java 复制代码
String selectDump(@Param("term") LocalDateTime term);

    @PostMapping(path = "/testDelete")
    @DS("attendance")
    @Operation(summary = "testDelete", tags = "考勤结果分析处理")
    public Message<TAttendanceResultDay> testDelete() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDate = LocalDate.parse("2026-09-13", formatter);
        LocalDateTime localDateTime = localDate.atStartOfDay();

        String string = tAttendanceResultDayMapper.selectDump(localDateTime);
        System.out.println(string);
    }

运行一下,结果如下:

shell 复制代码
09-13 14:27:56.407 [http-nio-8085-exec-1] DEBUG [98117dea9df645d3] c.h.p.mapper.TAttendanceResultDayMapper.selectDump ==>  Preparing: select dump(?) as termDump from dual [BaseJdbcLogger.java:137]
09-13 14:28:03.425 [http-nio-8085-exec-1] DEBUG [98117dea9df645d3] c.h.p.mapper.TAttendanceResultDayMapper.selectDump ==> Parameters: 2026-09-13T00:00(LocalDateTime) [BaseJdbcLogger.java:137]
09-13 14:28:03.470 [http-nio-8085-exec-1] DEBUG [98117dea9df645d3] c.h.p.mapper.TAttendanceResultDayMapper.selectDump <==      Total: 1 [BaseJdbcLogger.java:137]
Typ=180 Len=11: 120,126,9,13,1,1,1,0,0,0,0

这边发现,传过去的内容好像和数据库那边查出来的不一样:

shell 复制代码
Typ=180 Len=11: 120,126,9,13,1,1,1,0,0,0,0  这边传过去的
vs
Typ=12 Len=7: 120,126,9,13,1,1,1   数据库查出来的

做等值查询的时候,所以就匹配不到了。

如何修改

按照ai建议,修改如下:

使用cast函数:Oracle CAST 是一个‌显式数据类型转换函数‌,用于将一个值从一种数据类型转换为另一种兼容的数据类型

我们也写了个xml查询发过去的内容:

xml 复制代码
<select id="selectDump" resultType="java.lang.String">
    select dump(cast(#{term,jdbcType=TIMESTAMP} as date))   as termDump  from dual
</select>

运行一下:

shell 复制代码
09-13 14:49:28.984 [http-nio-8085-exec-2] DEBUG [a9cccd9a74aa435c] c.h.p.mapper.TAttendanceResultDayMapper.selectDump ==>  Preparing: select dump(cast(? as date)) as termDump from dual [BaseJdbcLogger.java:137]
09-13 14:49:28.985 [http-nio-8085-exec-2] DEBUG [a9cccd9a74aa435c] c.h.p.mapper.TAttendanceResultDayMapper.selectDump ==> Parameters: 2026-09-13T00:00(LocalDateTime) [BaseJdbcLogger.java:137]
09-13 14:49:28.999 [http-nio-8085-exec-2] DEBUG [a9cccd9a74aa435c] c.h.p.mapper.TAttendanceResultDayMapper.selectDump <==      Total: 1 [BaseJdbcLogger.java:137]
Typ=13 Len=8: 234,7,9,13,0,0,0,0

看到内容是:

shell 复制代码
Typ=13 Len=8: 234,7,9,13,0,0,0,0

和服务端的好像也不同:

shell 复制代码
SELECT dump(term) FROM T_ATTENDANCE_RESULT_DAY tard WHERE tard.OA_ACCOUNT = 'zhangsan' AND tard.TERM = DATE '2026-09-13'
Typ=12 Len=7: 120,126,9,13,1,1,1 

我们实际看看效果:

xml 复制代码
<delete id="deleteByBusinessKey">
    delete from t_attendance_result_day
     where oa_account = #{oaAccount,jdbcType=VARCHAR}
       and term = cast(#{term,jdbcType=TIMESTAMP} as date)
</delete>

看下面日志,真他么删掉了啊:

shell 复制代码
09-13 14:54:00.726 [http-nio-8085-exec-1] DEBUG [6fa9425af3924a57] c.h.p.mapper.TAttendanceResultDayMapper.selectDump ==>  Preparing: select dump(cast(? as date)) as termDump from dual [BaseJdbcLogger.java:137]
09-13 14:54:00.834 [http-nio-8085-exec-1] DEBUG [6fa9425af3924a57] c.h.p.mapper.TAttendanceResultDayMapper.selectDump ==> Parameters: 2026-09-13T00:00(LocalDateTime) [BaseJdbcLogger.java:137]
09-13 14:54:00.882 [http-nio-8085-exec-1] DEBUG [6fa9425af3924a57] c.h.p.mapper.TAttendanceResultDayMapper.selectDump <==      Total: 1 [BaseJdbcLogger.java:137]
Typ=13 Len=8: 234,7,9,13,0,0,0,0

09-13 14:54:00.883 [http-nio-8085-exec-1] DEBUG [6fa9425af3924a57] c.h.p.m.T.deleteByBusinessKey ==>  Preparing: delete from t_attendance_result_day where oa_account = ? and term = cast(? as date) [BaseJdbcLogger.java:137]
09-13 14:54:00.884 [http-nio-8085-exec-1] DEBUG [6fa9425af3924a57] c.h.p.m.T.deleteByBusinessKey ==> Parameters: zhangsan(String), 2026-09-13T00:00(LocalDateTime) [BaseJdbcLogger.java:137]
09-13 14:54:00.899 [http-nio-8085-exec-1] DEBUG [6fa9425af3924a57] c.h.p.m.T.deleteByBusinessKey <==    Updates: 1 [BaseJdbcLogger.java:137]

那这啥意思呢,我们传过去的是:

shell 复制代码
Typ=13 Len=8: 234,7,9,13,0,0,0,0

服务端是:

shell 复制代码
Typ=12 Len=7: 120,126,9,13,1,1,1 

这也不相等啊。

ai跟我说:

13是属于外部格式,外部格式(13)是小端直接编码:234,7 → 234+7×256 = 2026 年。

直接传localDateTime为啥不行

大哥又给我说了,是服务端端版本是oracle 11g,这个版本对于目前使用的java驱动来说,太低了。

xml 复制代码
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>23.2.0.0</version>
        <scope>compile</scope>
    </dependency>

支持的版本范围是:

https://www.oracle.com/database/technologies/faq-jdbc.html

最低支持的都是19.x版本,连12.x都不支持,别提11.x了

我当时是由于一个新增需求,才增加了这个java服务读这个oracle库,但为什么选了一个这么高的版本呢,也就几个月前的事,却是一点想不起来了。可能也没想那么多吧。

换回老版本的oracle驱动

换成老版本:

xml 复制代码
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>11.2.0.3</version>
    </dependency>

xml换回来;

xml 复制代码
    <select id="selectDump" resultType="java.lang.String">
        select dump(#{term,jdbcType=TIMESTAMP})   as termDump  from dual
    </select>

数据加回来,重试,直接就报错了,原来是ojdbc6根本不认识LocalDateTime这类类型:

这下,看来我当时选择了高版本的ojdbc8就是这个原因了。只是没考虑到这次遇到的新问题。

换到21.9.0.0

ai大哥让我改回一个稍微老点的版本,21.X,我挑了一个:

xml 复制代码
    <!-- Source: https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->  
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>21.9.0.0</version>
        <scope>compile</scope>
    </dependency>
    <!-- Source: https://mvnrepository.com/artifact/com.oracle.database.nls/orai18n -->
    <dependency>
        <groupId>com.oracle.database.nls</groupId>
        <artifactId>orai18n</artifactId>
        <version>21.9.0.0</version>
        <scope>compile</scope>
    </dependency>
shell 复制代码
09-13 15:36:09.340 [http-nio-8085-exec-1] DEBUG [1e8aa02a5a694076] c.h.p.mapper.TAttendanceResultDayMapper.selectDump ==>  Preparing: select dump(?) as termDump from dual [BaseJdbcLogger.java:137]
09-13 15:36:10.444 [http-nio-8085-exec-1] DEBUG [1e8aa02a5a694076] c.h.p.mapper.TAttendanceResultDayMapper.selectDump ==> Parameters: 2026-09-13T00:00(LocalDateTime) [BaseJdbcLogger.java:137]
09-13 15:36:10.480 [http-nio-8085-exec-1] DEBUG [1e8aa02a5a694076] c.h.p.mapper.TAttendanceResultDayMapper.selectDump <==      Total: 1 [BaseJdbcLogger.java:137]
Typ=180 Len=7: 120,126,9,13,1,1,1

09-13 15:36:11.702 [http-nio-8085-exec-1] DEBUG [1e8aa02a5a694076] c.h.p.m.T.deleteByBusinessKey ==>  Preparing: delete from t_attendance_result_day where oa_account = ? and term = ? [BaseJdbcLogger.java:137]
09-13 15:36:13.443 [http-nio-8085-exec-1] DEBUG [1e8aa02a5a694076] c.h.p.m.T.deleteByBusinessKey ==> Parameters: zhangsan(String), 2026-09-13T00:00(LocalDateTime) [BaseJdbcLogger.java:137]
09-13 15:36:13.458 [http-nio-8085-exec-1] DEBUG [1e8aa02a5a694076] c.h.p.m.T.deleteByBusinessKey <==    Updates: 1 [BaseJdbcLogger.java:137]

换回21.9.0.0版本后,发现dump内容变成了:

shell 复制代码
Typ=180 Len=7: 120,126,9,13,1,1,1

和最早的23.x版本,确实不同了:

shell 复制代码
Typ=180 Len=11: 120,126,9,13,1,1,1,0,0,0,0

无法查询问题--最终可行的方案

换成21.9.0.0版本

下面这样就可以:

java 复制代码
int deleteByBusinessKey(@Param("oaAccount") String oaAccount,
                            @Param("term") LocalDateTime term);
xml 复制代码
    <delete id="deleteByBusinessKey">
        delete from t_attendance_result_day
         where oa_account = #{oaAccount,jdbcType=VARCHAR}
           and term = #{term,jdbcType=TIMESTAMP}
    </delete>

保持23.x版本

方法1

用cast方式,

xml 复制代码
int deleteByBusinessKey(@Param("oaAccount") String oaAccount,
                            @Param("term") LocalDateTime term);
<delete id="deleteByBusinessKey">
    delete from t_attendance_result_day
     where oa_account = #{oaAccount,jdbcType=VARCHAR}
       and term = cast(#{term,jdbcType=TIMESTAMP} as date)
</delete>

方法2

xml 复制代码
    <delete id="deleteByBusinessKey">
        delete from t_attendance_result_day
         where oa_account = #{oaAccount,jdbcType=VARCHAR}
           and term = to_date(#{term,jdbcType=VARCHAR},'yyyy-MM-dd hh24:mi:ss')
    </delete>

int deleteByBusinessKey(@Param("oaAccount") String oaAccount,
                            @Param("term") String term);

这个就传字符串,最保险。再结合版本换成21.9,应该是最稳妥的。

方法3

xml 复制代码
动态拼sql:
<delete id="deleteByBusinessKey">
        delete from t_attendance_result_day
         where oa_account = #{oaAccount,jdbcType=VARCHAR}
           and term = timestamp '${term}'
</delete>

int deleteByBusinessKey(@Param("oaAccount") String oaAccount,
                            @Param("term") String term);
int i = tAttendanceResultDayMapper.deleteByBusinessKey("zhangsan", "2026-09-13 00:00:00");


下面这样写不行,必须动态拼sql才行:
<delete id="deleteByBusinessKey">
    delete from t_attendance_result_day
     where oa_account = #{oaAccount,jdbcType=VARCHAR}
       and term = timestamp #{term}
</delete>

插入问题

其实insert也会有问题,之前这个term字段都是定义成LocalDate的。插入的时候,比如赋值为:

java 复制代码
    TAttendanceResultDay day = new TAttendanceResultDay();
    day.setTerm(LocalDate.now());
    day.setOaAccount("demo");
    tAttendanceResultDayMapper.insert(day);

就像前面说的那样,LocalDate会被oracle驱动转换为它自己的TIMESTAMP,转的时候,就变成了这一天的12点。

shell 复制代码
2026-09-13 12:00:00.000

把字段类型弄成LocalDateTime就行了。

一个坑点

java 复制代码
TAttendanceResultDay day = new TAttendanceResultDay();
LocalDateTime now = LocalDateTime.now();
day.setTerm(now);
day.setOaAccount("demo");
day.setBadge("001140");
tAttendanceResultDayMapper.insert(day);
执行完上面的插入后,比如now是:2026-09-13T16:19:16.389,但最终在数据库是这样的: 2026-09-13 16:19:16.000,没有最后的毫秒部分。
    
String string = tAttendanceResultDayMapper.selectDump(now);
System.out.println(string); -- Typ=180 Len=11: 120,126,9,13,17,20,17,23,47,171,64


但是这边等值匹配的时候,是带了毫秒的,依然会删不掉:
int i = tAttendanceResultDayMapper.deleteByBusinessKey("demo", now, "001140");
System.out.println(i);

总结

看来看去,还是字符串格式最好,少了好多坑。

用这种算了:

xml 复制代码
    <delete id="deleteByBusinessKey">
        delete from t_attendance_result_day
         where oa_account = #{oaAccount,jdbcType=VARCHAR}
           and term = to_date(#{term,jdbcType=VARCHAR},'yyyy-MM-dd hh24:mi:ss')
    </delete>

int deleteByBusinessKey(@Param("oaAccount") String oaAccount,
                            @Param("term") String term);

参考

插入示例:

shell 复制代码
INSERT INTO your_table_name (date_column) VALUES (TO_DATE('2024-05-13', 'YYYY-MM-DD'));
或者:
INSERT INTO your_table_name (date_column) VALUES (DATE '2024-05-13');  

查询时怎么查:

sql 复制代码
select * from your_table_name where to_char(date_column,'yyyy-mm-dd') = '2024-05-13';  这个走不了索引
或者
select * from your_table_name where date_column = date '2024-05-13';
或者
select * from your_table_name where date_column = timestamp '2024-05-13 00:00:00';
或者
select * from your_table_name where date_column = to_date('2024-05-13','yyyy-mm-dd') 

select * from your_table_name where date_column >= to_date('2024-05-13','yyyy-mm-dd') and update_time < to_date('2024-05-14','yyyy-mm-dd');