sql >> Database >  >> RDS >> Oracle

oracle - converteer veel datumnotaties naar een enkele opgemaakte datum

Als je een goed idee hebt van alle mogelijke datumformaten, is het misschien makkelijker om brute kracht te gebruiken:

create or replace function clean_date
    ( p_date_str in varchar2)
    return date
is
    l_dt_fmt_nt sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll
        ('DD-MON-YYYY', 'DD-MON-YY', 'DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD'
         , 'DD/MM/YYYY', 'MM/DD/YYYY', 'YYYY/MM/DD', 'DD/MM/YY', 'MM/DD/YY');
    return_value date;
begin
    for idx in l_dt_fmt_nt.first()..l_dt_fmt_nt.last()
    loop
        begin
            return_value := to_date(p_date_str, l_dt_fmt_nt(idx));
            exit;
        exception
             when others then null;
        end;
    end loop;
    if return_value is null then
        raise no_data_found; 
    end if;
    return return_value;
exception
    when no_data_found then
        raise_application_error(-20000, p_date_str|| ' is unknown date format');
end clean_date;
/

Houd er rekening mee dat moderne versies van Oracle behoorlijk vergevingsgezind zijn met datumconversie. Deze functie verwerkte datums in formaten die niet in de lijst staan, met enkele interessante gevolgen:

SQL> select  clean_date('20160817') from dual;

CLEAN_DAT
---------
17-AUG-16

SQL> select  clean_date('160817') from dual;

CLEAN_DAT
---------
16-AUG-17

SQL> 

Wat de grenzen aantoont van geautomatiseerde gegevensopschoning in het licht van lakse regels voor gegevensintegriteit. Het loon van de zonde is corrupte data.

@AlexPoole stelt het gebruik van de 'RR' . ter sprake formaat. Dit element van het datummasker werd geïntroduceerd als een Y2K-kludge. Het is nogal deprimerend dat we het er bijna twee decennia in het nieuwe millennium nog steeds over hebben.

Hoe dan ook, het probleem is dit. Als we deze string '161225' . casten tot een datum welke eeuw heeft het? Nou, 'yymmdd' geeft 2016-12-15 . Klopt, maar hoe zit het met '991225' ? Hoe waarschijnlijk is dat de datum die we echt willen is 2099-12-15 ? Dit is waar de 'RR' formaat komt om de hoek kijken. In principe staat de eeuw standaard:nummers 00-49 standaard op 20, 50-99 standaard op 19. Dit venster werd bepaald door het Y2K-probleem:in 2000 was het waarschijnlijker dat '98 verwezen naar het recente verleden dan naar de nabije toekomst, en soortgelijke logica toegepast op '02 . Vandaar halverwege 1950. Let op:dit is een vast punt geen schuifraam. Naarmate we verder van het jaar 2000 komen, wordt dat draaipunt minder bruikbaar. Lees meer.

Hoe dan ook, het belangrijkste punt is dat 'RRRR' niet goed samengaat met andere datumformaten:to_date('501212', 'rrrrmmdd') hurls ora-01843:geen geldige maand. So, use 'RR'and test for it before using 'JJJJ'`. Dus mijn herziene functie (met wat opruimen) ziet er als volgt uit:

create or replace function clean_date
    ( p_date_str in varchar2)
    return date
is
    l_dt_fmt_nt sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll
        ('DD-MM-RR', 'MM-DD-RR', 'RR-MM-DD', 'RR-DD-MM'
         , 'DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY-DD-MM');
    return_value date;
begin
    for idx in l_dt_fmt_nt.first()..l_dt_fmt_nt.last()
    loop
        begin
            return_value := to_date(p_date_str, l_dt_fmt_nt(idx));
            exit;
        exception
             when others then null;
        end;
    end loop;
    if return_value is null then
        raise no_data_found; 
    end if;
    return return_value;
exception
    when no_data_found then
        raise_application_error(-20000, p_date_str|| ' is unknown date format');
end clean_date;
/

Het belangrijkste punt blijft:er is een limiet aan hoe slim we deze functie kunnen maken als het gaat om het interpreteren van datums, dus zorg ervoor dat je de leiding neemt met de beste pasvorm. Als je denkt dat de meeste van je datumreeksen passen bij dag-maand-jaar, zet dat dan eerst; je zult nog steeds een aantal verkeerde worpen krijgen, maar minder als je leidt met jaar-maand-dag.



  1. hoe dbms_scheduler te gebruiken om de taak elke 30 minuten uit te voeren

  2. Een PostgreSQL-database controleren

  3. Wat zijn databanken?

  4. Codeigniter - meerdere databaseverbindingen