oracle 无法转换加载到DATE列中的时间戳数据

l7mqbcuq  于 2023-04-05  发布在  Oracle
关注(0)|答案(1)|浏览(165)

我有一个简单的问题:我目前正在尝试将数据作为Excel文件插入到我的数据库(APEX)中。我正在加载的表之一是时间戳列yyyy-mm-dd hh:mm:ss,但我正在加载的列是日期格式mm/dd/yyyy。插入时,该列显示为日期mm/dd/yyyy,但当我尝试查询表查找日期时,没有找到数据。
以下是我的查询:SELECT * FROM my_table WHERE DATE_f = '01/20/2023'
我假设即使数据显示为Date,因为列表是Date列,它仍然是Timestamp...
如果你有什么问题,我可以修复它的任何想法?(转换我的列类型也许)(我需要数据作为日期格式,我不能在Excel文件中进行转换)
感谢帮助

taor4pac

taor4pac1#

在Oracle中,DATE是一种二进制数据类型,由7个字节组成,表示:世纪,世纪年,月,日,小时,分钟和秒。它总是有这7个组件,它 * 从来没有**存储在任何特定的人类可读格式。
因此,如果您加载的数据包含年到秒的分量,那么DATE仍将包含年到秒的分量。

  • (如果您加载的日期仅包含年到日的组件,那么您的DATE将包含这些年到日的组件,并将获得默认的午夜时间组件。

插入时,列显示为Date mm/dd/yyyy
这是您的客户端应用程序碰巧使用的显示格式;它与数据库在后台存储的二进制数据不同。
您的客户端应用程序(Apex)正在尝试提供帮助,并将二进制值转换为您(用户)可以理解的内容,并且通过将默认格式模型应用于日期来实现这一点。该模型恰好是mm/dd/yyyy,它不会显示日期的时间组件;但是那些时间分量即使没有被显示也仍然存在。
以下是我的查询:SELECT * FROM my_table WHERE DATE_f = '01/20/2023'
您的查询实际上是:

SELECT *
FROM   my_table
WHERE  DATE_f = TO_DATE(
                  '01/20/2023',
                  ( SELECT value
                    FROM   NLS_SESSION_PARAMETERS
                    WHERE  parameter = 'NLS_DATE_FORMAT' )
                );

因为你的NLS_DATE_FORMAT参数是mm/dd/yyyy,那么转换是成功的,日期将被赋予默认的时间成分午夜。所以这只会在你的数据库中的日期有一个午夜的时间成分时起作用;如果它有任何非mindnight时间分量,则它不能匹配它
你可以做的是在一个范围内匹配:

SELECT *
FROM   my_table
WHERE  DATE_f >= DATE '2023-01-20'
AND    DATE_f <  DATE '2023-01-21'

或者,您也可以在时间组件上进行匹配:

SELECT *
FROM   my_table
WHERE  DATE_f = DATE '2023-01-20' + INTERVAL '12:34:56' HOUR TO SECOND

或者,使用TIMESTAMP文字:

SELECT *
FROM   my_table
WHERE  DATE_f = TIMESTAMP '2023-01-20 12:34:56'

或者,使用TO_DATE

SELECT *
FROM   my_table
WHERE  DATE_f = TO_DATE('2023-01-20 12:34:56', 'YYYY-MM-DD HH24:MI:SS');

也可以使用TRUNC

SELECT *
FROM   my_table
WHERE  TRUNC(DATE_f) = DATE '2023-01-20';

但是Oracle不能在DATE_F列上使用索引,而需要在TRUNC(date_f)上使用基于函数的索引。使用范围或匹配精确的时间确实允许使用索引。
如果要更改Oracle用于从字符串到日期和日期到字符串的隐式转换的格式模型,则可以用途:

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

或者,如果你想对日期应用显式格式,那么你可以使用TO_CHAR

SELECT column1,
       column2,
       TO_CHAR(DATE_f, 'YYYY-MM-DD HH24:MI:SS') AS date_f
FROM   my_table
WHERE  DATE_f >= DATE '2023-01-20'
AND    DATE_f <  DATE '2023-01-21'

相关问题