如果你想在串改變 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個數字字符組成。但它仍然可能形成無效的「日期」。
不明白,你說這個字段是日期,但可以保存30個字符。請包括表格定義。 – Alfabravo
您想將字符串**轉換爲日期**。從你的標題和你的文章精確引用。現在,Oracle具有'TO_CHAR'和'TO_DATE'功能。如果你想將**轉換爲日期**,那麼這兩個函數中的哪一個(同樣,它們的名字是'TO_CHAR'和'TO_DATE'),你認爲它更可能是正確的嗎? – mathguy
該表是一個字符串(30)。我同意,我希望我們能夠控制數據如何存儲在表格中,但可悲的是我們沒有。 –