将SQL Oracle的字符串转换为日期字段

将SQL Oracle的字符串转换为日期字段,oracle,Oracle,我需要将字符串转换为日期字段。该字段存储30个字符。日期(如果存在)的格式为“yyyymmdd”(20170202)。在所有情况下,日期后面都有22个空格。我需要将此字段格式化为日期字段,如下所示:dd-mm-yyyy 我试过几个公式: TO_CHAR(PERSACTION.NEW_VALUE_02,'dd-mm-yyyyy'),TO_CHAR(PERSACTION.NEW_VALUE_02,'yyyyymmd'),修剪(TO_CHAR(PERSACTION.NEW_VALUE_02,'yyyy

我需要将字符串转换为日期字段。该字段存储30个字符。日期(如果存在)的格式为“yyyymmdd”(20170202)。在所有情况下,日期后面都有22个空格。我需要将此字段格式化为日期字段,如下所示:dd-mm-yyyy

我试过几个公式:
TO_CHAR(PERSACTION.NEW_VALUE_02,'dd-mm-yyyyy')
TO_CHAR(PERSACTION.NEW_VALUE_02,'yyyyymmd')
修剪(TO_CHAR(PERSACTION.NEW_VALUE_02,'yyyyymmdd'))
,错误消息:数字格式模型无效。欢迎并感谢您的专业知识。

您是否尝试过转换为日期格式,然后再次转换为字符格式


TO_CHAR(TO_DATE(peraction.NEW_VALUE_02,'yyyyymmdd'),'dd-mm-yyyy')
是否尝试转换为日期格式,然后再次转换为CHAR

TO_CHAR(TO_DATE(peraction.NEW_VALUE_02,'yyyyymmdd'),'dd-mm-yyyy')

我们应该做到这一点。rtrim删除字符串右侧的空格。然后我使用指定的日期格式将其转换为日期,然后再次将其转换为所需格式的字符串


我们应该做到这一点。rtrim删除字符串右侧的空格。然后我使用指定的日期格式将其转换为日期,然后再次将其转换为所需格式的字符串。

请,请,请不要存储日期和字符数据类型。这只会导致在使用日期数据类型时可以避免的问题。

请,请,请不要存储日期和字符数据类型。这只会导致在使用日期数据类型时可以避免的问题。

如果要将字符串20170202更改为另一个字符串,而不是实际的日期(没有固有的格式化文本表示),可以选择使用正则表达式对其进行转换,而不是转换为日期并返回:

select regexp_replace('20170202     ', '^(\d{4})(\d{2})(\d{2}) +$', '\3-\2-\1')
from dual;

REGEXP_REPLACE(
---------------
02-02-2017     
或者您可以使用
substr
而不是
regexp\u substr
,即使您必须调用它三次,它的性能也会更好;使用CTE只是为了避免重复该值:

with t(str) as (
  select '20170202     ' from dual
)
select substr(str, 7, 2) ||'-'|| substr(str, 5, 2) ||'-'|| substr(str, 1, 4)
from t;

SUBSTR(STR
----------
02-02-2017
如果您转换为日期并返回,您将发现任何无法转换的值,因为它们将导致引发异常。这意味着你有坏数据;当然,如果首先使用正确的数据类型,就可以避免这种情况。这些将转换任何旧的垃圾,根据字符串偏离您期望的模式的程度,结果会有所不同,但包括像“20170231”这样表示无效日期的字符串。在substr版本中,空值或仅包含空格的字符串将转换为奇数,但您可以将它们过滤掉

您可以看到一些与您的期望不符的样本数据所带来的变化:

with t(str) as (
  select '20170202     ' from dual
  union all select '20170231     ' from dual
  union all select '2017020c     ' from dual
  union all select '2017020      ' from dual
  union all select '201702021    ' from dual
  union all select '             ' from dual
  union all select null from dual
)
select str,
  regexp_replace(str, '^(\d{4})(\d{2})(\d{2}) +$', '\3-\2-\1') as reg,
  substr(str, 7, 2) ||'-'|| substr(str, 5, 2) ||'-'|| substr(str, 1, 4) as sub
from t;

STR           REG           SUB          
------------- ------------- -------------
20170202      02-02-2017    02-02-2017   
20170231      31-02-2017    31-02-2017   
2017020c      2017020c      0c-02-2017   
2017020       2017020       0 -02-2017   
201702021     201702021     02-02-2017   
                              -  -       
                            --           
使用锚和空格预期,正则表达式不会修改不完全由8个数字字符组成的任何内容。但是它仍然可以形成无效的“日期”。

如果您想将字符串20170202更改为另一个字符串,而不是实际的日期(没有内在的格式化文本表示),您可以选择使用正则表达式对其进行转换,而不是转换为日期并返回:

select regexp_replace('20170202     ', '^(\d{4})(\d{2})(\d{2}) +$', '\3-\2-\1')
from dual;

REGEXP_REPLACE(
---------------
02-02-2017     
或者您可以使用
substr
而不是
regexp\u substr
,即使您必须调用它三次,它的性能也会更好;使用CTE只是为了避免重复该值:

with t(str) as (
  select '20170202     ' from dual
)
select substr(str, 7, 2) ||'-'|| substr(str, 5, 2) ||'-'|| substr(str, 1, 4)
from t;

SUBSTR(STR
----------
02-02-2017
如果您转换为日期并返回,您将发现任何无法转换的值,因为它们将导致引发异常。这意味着你有坏数据;当然,如果首先使用正确的数据类型,就可以避免这种情况。这些将转换任何旧的垃圾,根据字符串偏离您期望的模式的程度,结果会有所不同,但包括像“20170231”这样表示无效日期的字符串。在substr版本中,空值或仅包含空格的字符串将转换为奇数,但您可以将它们过滤掉

您可以看到一些与您的期望不符的样本数据所带来的变化:

with t(str) as (
  select '20170202     ' from dual
  union all select '20170231     ' from dual
  union all select '2017020c     ' from dual
  union all select '2017020      ' from dual
  union all select '201702021    ' from dual
  union all select '             ' from dual
  union all select null from dual
)
select str,
  regexp_replace(str, '^(\d{4})(\d{2})(\d{2}) +$', '\3-\2-\1') as reg,
  substr(str, 7, 2) ||'-'|| substr(str, 5, 2) ||'-'|| substr(str, 1, 4) as sub
from t;

STR           REG           SUB          
------------- ------------- -------------
20170202      02-02-2017    02-02-2017   
20170231      31-02-2017    31-02-2017   
2017020c      2017020c      0c-02-2017   
2017020       2017020       0 -02-2017   
201702021     201702021     02-02-2017   
                              -  -       
                            --           

使用锚和空格预期,正则表达式不会修改不完全由8个数字字符组成的任何内容。但它仍然可以形成无效的“日期”。

不理解您说的字段是日期,但包含30个字符。请包括表定义。您想将字符串转换为日期。从你的标题和文章中准确引用。现在,Oracle具有到字符的
和到日期的
功能。如果要转换为日期,您认为这两个函数中的哪一个更可能是正确的(同样,它们的名称是
to_CHAR
to_date
)表是一个字符串(30)。我同意,我希望我们能够控制数据在表中的存储方式,但遗憾的是我们没有。另一方面,如果您想转换为日期,那么就没有“格式”——日期字段没有格式。格式仅适用于字符串,当您将字符串转换为日期时(当您将数据以正确的数据类型(即日期)存储在表中时),以及当您将日期转换回字符串时,仅用于重新编写。不理解您说的字段是日期,但包含30个字符。请包括表定义。您想将字符串转换为日期。从你的标题和文章中准确引用。现在,Oracle具有到字符的
和到日期的
功能。如果要转换为日期,您认为这两个函数中的哪一个更可能是正确的(同样,它们的名称是
to_CHAR
to_date
)表是一个字符串(30)。我同意,我希望我们能够控制数据在表中的存储方式,但遗憾的是我们没有。另一方面,如果您想转换为日期,那么就没有“格式”——日期字段没有格式。转换stri时,格式仅适用于字符串