我需要将字符串转换为日期字段。该字段存储30个字符。日期(如果存在)的格式为' yyyymmdd' (20170202)。在所有情况下,日期后有22个空格。我需要将此字段格式化为这样的日期字段:dd-mm-yyyy。
我尝试了几个公式:
TO_CHAR(PERSACTION.NEW_VALUE_02, 'dd-mm-yyyy')
,TO_CHAR(PERSACTION.NEW_VALUE_02, 'yyyymmdd')
,trim(TO_CHAR(PERSACTION.NEW_VALUE_02, 'yyyymmdd'))
,错误消息:无效的数字格式模型。欢迎并感谢您的专业知识。
答案 0 :(得分:3)
to_char(to_date( rtrim(new_value_02), 'yyyymmdd'), 'dd-mm-yyyy')
应该做的伎俩。 rtrim删除字符串右侧的空格。然后我使用指定的日期格式将其转换为日期,然后再以所需的格式将其转换为字符串。
答案 1 :(得分:2)
是否曾尝试转换为日期格式,然后又转换为char?
TO_CHAR(TO_DATE(PERSACTION.NEW_VALUE_02,'yyyymmdd'),'dd-mm-yyyy')
答案 2 :(得分:1)
请,请不要存储DATE和CHARACTER数据类型。这只会导致在使用DATE数据类型时可以避免的问题。
答案 3 :(得分:0)
如果要将字符串 20170202更改为另一个字符串而实际上不是日期(没有固有的格式化文本表示),您可以选择使用常规表达式转换它,而不是转换为日期和返回:
select regexp_replace('20170202 ', '^(\d{4})(\d{2})(\d{2}) +$', '\3-\2-\1')
from dual;
REGEXP_REPLACE(
---------------
02-02-2017
或者您可以使用substr
代替regexp_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'代表无效的日期。并且null值或仅仅空格的字符串将使用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个数字字符组成的内容。但它仍然可以形成无效的日期'。