0

私は Oracle 11G を使用しており、日付がデータベースに手動で入力される日付列 (Var char 2) があり、残念ながら多くの場合、無効な日付が入力されています。ある種の REGEXP LIKE ステートメントを使用して有効な日付フィールドのみを選択したいと思います。選択したい有効な形式は次のとおりです。

DATE

JULY 31, 2009
7/31/2009
31-JUL-09

これら 3 つの可能な形式にないものは、選択したくありません。これらの有効な日付形式を選択するための REGEXP またはその他の方法を考え出すのを手伝ってくれませんか。前もって感謝します。

4

1 に答える 1

1

正規表現の代わりに PL/SQL を試してください。大幅に遅くなりますが、より安全で、保守と拡張が容易になります。これを正しく行うには、Oracle 形式モデルに依存する必要があります。正規表現を使用してこの情報を検証しようとする試みを数多く見てきましたが、正しく行われることはめったにありません。

パフォーマンスを本当に気にするなら、本当の答えはデータ モデルを修正することです。

コードとテスト ケース:

--Function to convert a string to a date, or return null if the format is wrong.
create or replace function validate_date(p_string in string) return date is
begin
    return to_date(p_string, 'MONTH DD, YYYY');
exception when others then
    begin
        return to_date(p_string, 'MM/DD/YYYY');
    exception when others then
        begin
            return to_date(p_string, 'DD-MON-RR');
        exception when others then
            return null;
        end;
    end;
end;
/

--Test individual values
select validate_date('JULY 31, 2009') from dual;
2009-07-31
select validate_date('7/31/2009') from dual;
2009-07-31
select validate_date('31-JUL-09') from dual;
2009-07-31
select validate_date('2009-07-31') from dual;
<null>

簡単なパフォーマンス テスト:

--Create table to hold test data
create table test1(a_date varchar2(1000)) nologging;

--Insert 10 million rows
begin
    for i in 1 .. 100 loop
        insert /*+ append */ into test1
        select to_char(sysdate+level, 'MM/DD/YYYY') from dual connect by level <= 100000;

        commit;
    end loop;
end;
/

--"Warm up" the database, run this a few times, see how long a count takes.
--Best case time to count: 2.3 seconds
select count(*) from test1;


--How long does it take to convert all those strings?
--6 minutes... ouch
select count(*)
from test1
where validate_date(a_date) is not null;
于 2013-04-01T03:30:05.007 に答える