2017-02-28 18 views
0

文字列を日付フィールドに変換する必要があります。フィールドは30文字を格納します。日付は、存在する場合、 'yyyymmdd'(20170202)としてフォーマットされます。すべての場合において、日付は22スペース後になります。私はこのフィールドを次のような日付フィールドとしてフォーマットする必要があります:dd-mm-yyyy。SQLの文字列を日付フィールドに変換する

私が試したいくつかの式:無効な数値書式モデル:エラーメッセージを 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という関数があります。 ** **をdate **に変換したい場合は、これらの2つの関数(どちらも '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が** date **に変換したい場合、なぜ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  

それとも、より良いあなたが3回それを呼び出すために持っていても実行することの代わりにregexp_substrsubstrを、使用することができます。あなたは、彼らは例外がスローされますよう、あなたが、変換できない任意の値を明らかになり、日付とバックに変換しなければ

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 

:ちょうど値の繰り返しを避けるためにCTEを使用。それは悪いデータがあることを意味します。もちろん、最初の正しいデータ型を使用することによって回避されていました。これらは、文字列が予想されるパターンからどのくらい離れているかに応じてさまざまな結果を持つ古いゴミを変換しますが、無効な日付を表す '20170231'のような文字列も含みます。 null値や空白文字列は、substrバージョンでは奇妙なものに変換されますが、それらをフィルタリングすることができます。

あなたはあなたの期待と一致していないいくつかのサンプルデータとなるだろう変動の種類見ることができます:正規表現はdoesnの何かを変更しない、アンカーと空白期待して

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文字の数字で構成されています。しかし、それはまだ無効な「日付」を形成することができます。

関連する問題