2017-10-11 1 views
0

私はさまざまなデータの列column_name VARCHAR2を持っています。 DATEデータ型に変換するには、私は次の式を書いた:Oracle VARCHAR2をDATEに変換し、無効なデータを除外します

SELECT TO_DATE(column_name, 'YYYY/MM/DD') FROM schema.table; 

をしかし、それは私にエラーを与える:

ORA-01841: (full) year must be between -4713 and +9999, and not be 0 01841. 00000 - "(full) year must be between -4713 and +9999, and not be 0"

*Cause: Illegal year entered

*Action: Input year in the specified range

列は "20161111" のようなNULLspace00000000と文字列の日付で構成されています。

私はDECODEを使用することにしました無効なデータを除外するために:

SELECT DECODE(column_name, 
       '', NULL, 
       '00000000', NULL, 
       TO_DATE(column_name, 'YYYY/MM/DD')) 
FROM schema.table; 

しかし、この場合には、私は次のエラーを取得:

ORA-01841: (full) year must be between -4713 and +9999, and not be 0 01841. 00000 - "(full) year must be between -4713 and +9999, and not be 0"

*Cause: Illegal year entered

*Action: Input year in the specified range

データの例を:

| # | column_name | 
|---|-------------| 
| 1 | 00000000 | 
| 2 |    | 
| 3 | (null)  | 
| 4 | 20161111 | 

何午前私は間違っている?

すべての無効なデータをDECODEの場合に含めないで除外するソリューションはありますか?

+0

列のサンプルデータを表示できますか? –

+1

写真を貼り付けたり、テキストを使用したりしないでください。 –

+0

あなたは '20161111'を有効とみなしますか? (すなわち2016-11-11) –

答えて

2

あなたはこのような関数を書くことができ:

CREATE OR REPLACE FUNCTION VARCHAR_TO_DATE(str IN VARCHAR2) RETURN DATE AS 
BEGIN 
    RETURN TO_DATE(str, 'YYYY/MM/DD'); 
EXCEPTION 
    WHEN OTHERS THEN 
     RETURN NULL; 
END; 

その後、無効な文字列はNULL値になります

SELECT varchar_to_date(column_name) FROM schema.table; 

として使用します。

+0

良い答え - 他のアプローチは、必ずしもOracle日付検証の少なくとも一部を複製するだろう –

1

は、例外を処理しますuser-defined functionを書く:

CREATE FUNCTION parse_Date(
    in_string  VARCHAR2, 
    in_format  VARCHAR2 DEFAULT 'YYYY/MM/DD', 
    in_nls_params VARCHAR2 DEFAULT NULL 
) RETURN DATE DETERMINISTIC 
AS 
BEGIN 
    RETURN TO_DATE(in_string, in_format, in_nls_params); 
EXCEPTION 
    WHEN OTHERS THEN 
    RETURN NULL; 
END; 
/

次に、あなたが行うことができます:

SELECT parse_Date(column_name, 'YYYY/MM/DD') 
FROM schema.table 

そうでなければ、あなたがregular expressions to match different valid date patternsを使用することができます。

1

あなただけCASEREGEXP_LIKE()を使用することができます。

SELECT (CASE WHEN REGEXP_LIKE(column_name, '^[12][0-9]{3}/[01][0-9]/[0123][0-9]$') 
      THEN TO_DATE(column_name, 'YYYY/MM/DD') 
     END) 

は明らかに、これは完璧なソリューションではありませんが、それは多くの状況下で動作します。

関連する問題