【问题标题】:Converting ISO Date VARCHAR into DATE YYYY-MM-DD HH:MM:SS in oracle在 oracle 中将 ISO Date VARCHAR 转换为 DATE YYYY-MM-DD HH:MM:SS
【发布时间】:2018-03-23 10:02:40
【问题描述】:

我在 TABLE1 的 oracle VARCHAR 列中有 ISO 日期格式,我必须将此值插入到 TABLE2 中,其中我的列数据类型为 DATE。

例如 1:

  • VARCHAR 字符串 Date1 - 2018-03-23T00:00:00.000+00:00
  • 我想将日期数据类型转换为 - MM-DD-YYYY

当使用下面的查询得到错误时,

INSERT INTO DATE_TEMP (DATE_VALUE) VALUES  (TO_DATE('2018-03-23T00:00:00.000+00:00','DD-MM-YYYY'));

错误代码:

ORA-01861: literal does not match format string

例如 2: - VARCHAR 字符串 Dat2 - 2018-03-23T12:34:56.123+00:00

INSERT INTO DATE_TEMP (DATE_VALUE) VALUES TO_TIMESTAMP_TZ('2018-03-23T12:34:56.123+00:00', 'yyyy-mm-dd"T"hh24:mi:ss.ff3TZH:TZM');

错误代码:

ORA-03001: unimplemented feature

【问题讨论】:

  • 您缺少值周围的括号。应该是 values ( to_timestamp_tz ... ) 而不是 values to_timestamp_tz ....
  • 谢谢 :) 它有效

标签: oracle date oracle11g


【解决方案1】:

如果日期后面的所有内容都是“0”(没有小时、分钟、...,如您的示例所示),那么它相当简单:

insert into table2 (date_column)
select to_date(substr(date_column, 1, 10), 'yyyy-mm-dd')
  from table1

【讨论】:

  • 感谢您的询问,如果我有以下格式 2018-03-23T15:16:09.132+00:00
  • 你会使用 TO_TIMESTAMP_TZ,正如 a_horse 在他的回答中显示的那样。
  • 当我执行此查询时,它显示以下错误“ORA-01841: (full) year must be between -4713 and +9999, and not be 0”
  • 如果值为2018-01-01T00:00:00+08:00,那么这将忽略时区并将日期插入为2018-01-01,如果将所有时间转换为一致的时区,则UTC时间实际上是2017-12-31T16:00:00Z.
【解决方案2】:

使用TO_TIMESTAMP_TZ( date_string, format_model ) 将其转换为TIMESTAMP WITH TIMEZONE 数据类型,然后您可以使用AT TIME ZONE 'UTC' 将所有值转换为公共时区(因为您使用的是DATE 列并且这不存储时区信息)并使用CAST( previous_value AS DATE ) 将其显式转换为DATE 数据类型或允许Oracle 在INSERT 语句中执行隐式转换:

SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE date_temp ( date_value DATE );

查询 1

INSERT INTO DATE_TEMP (
  DATE_VALUE
) VALUES(
  TO_TIMESTAMP_TZ(
    '2018-03-23T00:00:00.000+00:00',
    'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM'
  ) AT TIME ZONE 'UTC'
)

INSERT INTO DATE_TEMP (
  DATE_VALUE
) VALUES(
  TO_TIMESTAMP_TZ(
    '2018-03-23T12:34:56.123+01:00',     -- Note: Different time zone
    'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM'
  ) AT TIME ZONE 'UTC'
)

SELECT * FROM DATE_TEMP

Results

|           DATE_VALUE |
|----------------------|
| 2018-03-23T00:00:00Z |
| 2018-03-23T11:34:56Z | -- Note: value has been converted to the UTC time zone

顺便说一句:

我想将日期数据类型转换为 - MM-DD-YYYY

日期没有格式 - 它是 stored internally to the database 为 7 字节(表示年、月、日、小时、分钟和秒),直到您使用的任何用户界面(即 SQL/Plus 、SQL Developer、Java 等)尝试将其显示给您,即用户,并将其转换为您认为有意义的内容(通常是字符串),日期具有格式。

如果您只想要它作为日期而不想要时间组件,那么您可以使用 TRUNC( date_value ) 函数将您的值截断回午夜。

更新

是否可以将表1的记录插入表2。这样我们不想手动传递值。

SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE date_temp ( date_value DATE );

CREATE TABLE string_temp ( string_value VARCHAR2(50) );

INSERT INTO string_temp
SELECT '2018-03-23T00:00:00.000+00:00' FROM DUAL UNION ALL
SELECT '2018-03-23T12:34:56.123+01:00' FROM DUAL;

查询 1

INSERT INTO DATE_TEMP ( DATE_VALUE )
SELECT TO_TIMESTAMP_TZ(
         string_value,
         'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM'
       ) AT TIME ZONE 'UTC'
FROM   string_temp


SELECT * FROM DATE_TEMP

Results

|           DATE_VALUE |
|----------------------|
| 2018-03-23T00:00:00Z |
| 2018-03-23T11:34:56Z |

【讨论】:

  • 感谢您的回答,是否可以将表 1 中的记录插入表 2。通过这种方式,我们不想手动传递值。实际上它有十万条记录,不可能通过硬编码的日期参数来插入查询。
【解决方案3】:

您的字符串包含时区信息,因此您需要使用to_timestamp_tz,而不是to_date

to_timestamp_tz('2018-03-23T00:00:00.000+00:00', 'yyyy-mm-dd"T"hh24:mi:ss.ff3TZH:TZM')

如有必要,可以将其转换为日期。

在线示例:http://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=021438eeec836b441b7f23ca57ff5af4

【讨论】:

  • INSERT INTO DATE_TEMP VALUES( TO_TIMESTAMP_TZ( '2018-03-22T12:34:56.123+01:00', 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM' ) ); 将被隐式转换为时间为下午 12 点的日期,并忽略时区为 +01:00。由于时区将丢失,最好在转换为日期之前将时区更改为一致的时区。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 2018-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多