Oracle数据库Date类型丢失日期精度问题

本文详细介绍了在Java1.5环境下,使用MyBatis和Oracle10gr2时,从JSP页面获取日期yyyy-MM-ddHH:mm:ss格式后存入数据库导致精度丢失的解决方案。通过统一配置时间类型,确保日期数据正确存储和展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境:

       Java 1.5,MyBatis,Oracle10gr2

 

问题:

       在项目开发中,发现使用日期控件从JSP页面中获得格式化后的日期"yyyy-MM-dd HH:mm:ss",存入Oracle数据库后,会发现日期全部变为"yyyy-MM-dd 12:00:00”,丢失时间精度。

 

解决:

      思路:统一配置的时间类型。

1、Oracle数据库中,日期类型的数据,定义为Date类型。

 

alert table test add column EDIT_DATE DATE;

 

2、在MyBatis的test类的配置文件中,定义Date类型为TIMESTAMP。

 

    resultMap节点:

 <result column="EDIT_DATE" jdbcType="TIMESTAMP" property="testDate" />

    insert节点

   

<isNotNull prepend="," property="editDate">
    #editDate:TIMESTAMP#
</isNotNull>

  

3、在JAVA类中,定义DATE类型为java.util.Date。

 

import java.util.Date;

private Date editDate;

 

4、在JSP录入页面,定义日期格式:

   

<input type="text" name="editDate" id="editDate" onfocus="WdatePicker({skin:'whyGreen',dateFmt:'yyyy-MM-dd HH:mm:ss', readOnly:true,onpicked:function(){}})" />

 

5、在查询结果输出页面,定义日期格式:

 

<fmt:formatDate value="${result.edittDate}" pattern="yyyy-MM-dd HH:mm:ss"/>

 

问题解决,日期可正常展示。

<think>我们参考了引用[1]和引用[3]中的方法,以及引用[5]中关于两种类型区别的说明。 在Oracle中,TIMESTAMP类型DATE类型的主要区别在于精度(TIMESTAMP可以精确到纳秒,而DATE只精确到秒)和存储方式。 转换目标:将TIMESTAMP类型转换为DATE类型(即只保留到秒,去掉纳秒部分,同时不包含时区信息)。 方法1(推荐):使用CAST函数 这是最标准的方法,使用CAST函数将TIMESTAMP显式转换为DATE类型。 示例: SELECT CAST(your_timestamp_column AS DATE) AS converted_date FROM your_table; 方法2:使用+0操作(如引用[1]所述) 这种方法利用了Oracle的隐式转换,在TIMESTAMP值上加上0(一个数字),Oracle会自动将TIMESTAMP转换为DATE。 示例: SELECT your_timestamp_column + 0 AS converted_date FROM your_table; 方法3:使用TRUNC函数(如果需要同时去掉时间部分,只保留日期) 如果不仅要去掉纳秒,还要去掉时间部分(时分秒),可以使用TRUNC函数。 示例: SELECT TRUNC(your_timestamp_column) AS converted_date FROM your_table; 注意: - 方法1和方法2都会将TIMESTAMP转换为DATE,但会保留时间部分(精确到秒),而方法3会去掉时间部分(即时间部分变为00:00:00)。 - 根据引用[5],TIMESTAMP类型可能有更高的精度,转换到DATE类型时会丢失纳秒(或微秒)部分的信息。 因此,根据需求选择: 如果只需要精确到秒,且保留时间部分,用方法1或方法2。 如果只需要日期部分(不要时间),用方法3。 示例场景: 假设有一张表orders,其中有一个TIMESTAMP类型的字段order_time,存储了订单时间(精确到微秒)。 我们想将其转换为DATE类型(精确到秒)进行查询: 方法1: SELECT CAST(order_time AS DATE) AS order_date FROM orders; 方法2: SELECT order_time + 0 AS order_date FROM orders; 两种方法的结果都是DATE类型,时间部分精确到秒。 关于时区(参考引用[2]): 注意,TIMESTAMP类型本身不存储时区信息(除非是TIMESTAMP WITH TIME ZONE或TIMESTAMP WITH LOCAL TIME ZONE),而DATE类型也不存储时区。 所以转换过程中不会涉及时区转换,只是精度截断。 如果原始数据是TIMESTAMP WITH TIME ZONE类型,则转换时需要注意: 使用CAST转换时,会先将时间转换为数据库所在时区的时间,然后再转换为DATE类型。 例如:CAST(your_timestamp_with_tz AS DATE) 会先将时间转换为数据库时区的时间,然后去掉时区信息,再截断到秒。 因此,在转换带时区的TIMESTAMP时,请确保数据库时区设置正确,或者使用AT TIME ZONE先转换时区。 总结: 推荐使用CAST函数进行显式转换,这样代码更清晰。 相关问题: 1. 如何将TIMESTAMP WITH TIME ZONE类型转换为DATE类型? 2. 在Oracle中,DATE类型和TIMESTAMP类型在存储和性能上有何差异? 3. 如何将DATE类型转换为TIMESTAMP类型?</think>### Oracle 中将 TIMESTAMP 转换为 DATE 类型的方法 在 Oracle 数据库中,将 TIMESTAMP 类型转换为 DATE 类型主要有以下三种方法,根据引用[1][3][5]的信息整理: #### 1. **使用 `CAST` 函数(推荐方法)** ```sql SELECT CAST(your_timestamp_column AS DATE) AS converted_date FROM your_table; ``` - ✅ **优点**:标准 SQL 语法,显式转换,代码可读性强 - ⚠️ **注意**:会丢弃纳秒精度DATE 类型只保留到秒)[^5] #### 2. **使用 `+0` 操作符(隐式转换)** ```sql SELECT your_timestamp_column + 0 AS converted_date FROM your_table; ``` - ✅ **优点**:简洁高效(如引用[1]所述) - ⚠️ **注意**:本质是隐式类型转换,可能在不同 Oracle 版本中表现有差异 #### 3. **使用 `TRUNC` 函数(仅取日期部分)** ```sql SELECT TRUNC(your_timestamp_column) AS date_only FROM your_table; ``` - ✅ **优点**:直接获取日期部分(时间归零到 00:00:00) - 💡 **适用场景**:不需要时间部分的统计查询 --- ### 关键差异说明(引用[5]) | 特性 | TIMESTAMP 类型 | DATE 类型 | |--------------|-------------------------|------------------------| | **精度** | 最高纳秒级(默认微秒) | 精确到秒 | | **存储空间** | 7-11 字节 | 7 字节固定 | | **时区支持** | 有带时区的变体 | 无时区信息 | | **默认格式** | 'DD-MON-YY HH.MI.SS.FF' | 'DD-MON-YY' | --- ### 实际应用示例 **场景**:将订单表的 TIMESTAMP 字段转为 DATE 用于日报 ```sql -- 方法1:完整日期时间(保留时分秒) SELECT order_id, CAST(order_time AS DATE) AS order_date FROM orders; -- 方法2:仅日期部分(时间归零) SELECT order_id, TRUNC(order_time) AS order_day FROM orders WHERE TRUNC(order_time) = DATE '2023-10-01'; ``` > **重要提示**: > 1. 转换时会自动**丢弃纳秒/微秒精度**(DATE 类型只存储到秒)[^5] > 2. 带时区的 TIMESTAMP(`TIMESTAMP WITH TIME ZONE`)需先用 `AT TIME ZONE` 处理时区[^2] > 3. 在 WHERE 条件中使用 `TRUNC()` 可避免全表扫描(需配合函数索引)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值