如何以所需的格式获取此时间戳,Oracle SQL

时间:2018-07-10 14:26:45

标签: sql oracle timestamp

我首先运行以下命令,并得到以下结果:

select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;

TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 10:21:40

这是我要存储 TIMESTAMP 对象的格式。

不过,当我将其转换回来时,它不是我想要的格式:

select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;

TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 10.21.40.000000000 AM

实际上,它将2018更改为结尾,将07设置为“ JUL”,而10则位于前面。时间也由点分隔,具有多个0和一个AM。

我该如何解决?我是SQL开发的新手,所以不确定格式。

非常感谢您

3 个答案:

答案 0 :(得分:3)

就像@Gordon所说的那样,时间戳(和日期)不是以您会认识到的格式存储的,Oracle会使用您实际上不需要了解或检查的内部表示形式(但是如果您对此类型感兴​​趣的话,会记录下来)的东西。)

查询时间戳时,时间戳将使用客户端的NLS设置显示,除非您的客户端将其覆盖。我可以设置会话以匹配您所看到的内容:

alter session set nls_timestamp_format = 'DD-MON-RR HH.MI.SS.FF AM';

select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS') from dual;

TO_CHAR(SYSTIMESTAM
-------------------
2018-07-10 15:37:31

select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;

TO_TIMESTAMP(TO_CHAR(SYSTIMESTA
-------------------------------
10-JUL-18 03.37.31.000000000 PM

我可以更改它,以查看您想要看到的内容:

alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS';

select to_timestamp(to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') from dual;

TO_TIMESTAMP(TO_CHA
-------------------
2018-07-10 15:37:32

但是您要做的就是将带有时区的时间戳(systimestamp是时间戳)转换为字符串,然后再转换为时间戳。您将丢失时区部分以及任何小数秒;您也可以使用cast

select cast(systimestamp as timestamp(0)) from dual;

CAST(SYSTIMESTAMPAS
-------------------
2018-07-10 15:37:32

您可以使用默认的timestamp_tz格式查看时区和小数秒:

select systimestamp from dual;

SYSTIMESTAMP                        
------------------------------------
2018-07-10 15:37:33.776469000 +01:00

并使用其他alter进行更改:

alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS.FF3 TZH:TZM';

select systimestamp from dual;

SYSTIMESTAMP                  
------------------------------
2018-07-10 15:37:34.070 +01:00

如果您真正要谈论的是在表中存储时间戳,那么这并不完全相关,但是表明存在差异。

在表中输入数据类型timestamp(或timestamp with time zonetimestamp with local time zone),最后只需要担心将值格式化为字符串以呈现给最终用户可能的时刻。

当确实需要显示它时,如果显示格式对您很重要,则可以使用to_char()和显式格式掩码-不要假设其他任何运行您的查询的人都具有相同的NLS设置。如您所见,很容易更改它们以修改输出。 (大多数客户端可以通过一种方法来设置默认值,因此不必每次连接都执行相同的alter命令;例如,在SQL Developer中,从“工具”->“首选项”->“数据库”->“ NLS”) 。如果要始终显示相同的格式,请使用类似以下内容的

select to_char(your_column, 'YYYY-MM-DD HH24:MI:SS') as column_alias
from your_table
where your_column < timestamp '2018-01-01 00:00:00'

还显示了使用时间戳文字过滤的列值(仍为时间戳)。

答案 1 :(得分:2)

  

这是我要存储TIMESTAMP对象的格式。

这是一个常见的误解-时间戳(和日期)数据类型没有格式;它们以20字节(或7字节表示日期)的形式存储在数据库中representing

  • 年(2个字节),
  • 月,日,小时,分钟,整数秒(每个1字节),
  • 小数秒(4个字节),
  • 时区偏移小时(1个字节)
  • 时区偏移分钟(1个字节)
  • 其他数据(包括时区位置)(7个字节)

您可以使用DUMP函数查看字节:

SELECT DUMP( your_timestamp_column ) FROM your_table;

数据库将对这20个字节进行操作,而不使用任何格式。但这对向用户显示没有用,因此您用于访问数据库的用户界面(SQL / Plus,SQL Developer,Toad,Java,C#等)将从数据库接收这些原始字节,并且将默默地将它们格式化为用户(您)这种可理解的格式。

您实际上要问的是:

  

如何获取用于访问Oracle数据库的应用程序,以更改用于显示TIMESTAMP数据类型的默认格式?

对于SQL / Plus(和SQL Developer),您可以使用NLS_TIMESTAMP_FORMAT会话参数:

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

然后:

SELECT SYSTIMESTAMP FROM DUAL;

将输出:

2018-07-10 16:24:53

但是,这仅设置用户当前会话的默认格式。其他用户可以设置自己的参数,并可以在会话期间更改值,因此您不应依赖此参数来提供一致的格式。

相反,如果要使用特定格式的TIMESTAMP,则应将其转换为可以具有格式的数据类型-字符串。

SELECT TO_CHAR( SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI:SS' ) FROM DUAL;

然后,用户将其默认时间戳格式更改为什么都没有关系-您的值将始终按照您期望的格式设置。

答案 2 :(得分:0)

因此,根据您上面的答复,听起来您可能正在尝试做实际上不需要做的事情。

正如Gordon所述,时间戳以内部格式存储,因此您可以使用值来处理。如果您将字段存储为时间戳记数据类型,则无需关心它在数据库中的格式,您只需要关心它最后如何查询。您可以使用to_char显示日期字段,并且如果您正确构建了查询,则仍可以使用日期范围。

    select to_char(systimestamp, 'YYYY-MM-DD HH24:MI:SS')
    from dual
    WHERE systimestamp <= current_timestamp;

我认为不使用to_char并丢失数据类型就无法显示您所描述的时间戳。