2017-02-28 84 views
0

我需要將字符串轉換爲日期字段。該字段存儲30個字符。日期如果存在,則格式爲「yyyymmdd」(20170202)。在所有情況下,日期之後有22個空格。我需要將此字段格式化爲日期字段,如下所示:dd-mm-yyyy。將字符串轉換爲日期字段爲SQL Oracle

我試過幾個公式: 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

不明白,你說這個字段是日期,但可以保存30個字符。請包括表格定義。 – Alfabravo

+0

您想將字符串**轉換爲日期**。從你的標題和你的文章精確引用。現在,Oracle具有'TO_CHAR'和'TO_DATE'功能。如果你想將**轉換爲日期**,那麼這兩個函數中的哪一個(同樣,它們的名字是'TO_CHAR'和'TO_DATE'),你認爲它更可能是正確的嗎? – mathguy

+0

該表是一個字符串(30)。我同意,我希望我們能夠控制數據如何存儲在表格中,但可悲的是我們沒有。 –

回答

2

曾嘗試轉換爲日期格式,然後再次char?

TO_CHAR(TO_DATE(PERSACTION.NEW_VALUE_02,'yyyymmdd'),'dd-mm-yyyy')

+1

如果OP想要轉換爲** date **,爲什麼需要'TO_CHAR'? – mathguy

+0

因爲它需要是char。如Tania所問,該值存儲在日期字段中的文本字段中。 –

3
to_char(to_date(rtrim(new_value_02), 'yyyymmdd'), 'dd-mm-yyyy') 

應該做的伎倆。 rtrim刪除字符串右側的空格。然後使用指定的日期格式將其轉換爲日期,然後再以所需的格式將其轉換爲字符串。

+1

如果OP想要轉換爲**日期**,爲什麼需要'TO_CHAR'? – mathguy

+0

這工作完美,我會保留這個以備將來使用,非常感謝你 –

+1

@mathguy好點。我加了這個,因爲他特別提到了日期格式。但數據類型Date中的日期沒有格式,它只是特定日期的表示。只需將to_char留出,你就會有一個日期。 –

1

請請不要存儲DATE和CHARACTER數據類型。這隻會導致使用DATE數據類型時可以避免的問題。

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'之類的字符串。只有空格的空值或字符串將被轉換爲與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個數字字符組成。但它仍然可能形成無效的「日期」。