Oracle
 sql >> база данни >  >> RDS >> Oracle

oracle - конвертирайте много формати за дата в една форматирана дата

Ако имате добра представа за всички възможни формати за дата, може да е по-лесно да използвате груба сила:

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;
/

Имайте предвид, че съвременните версии на Oracle са доста прощаващи с преобразуване на дата. Тази функция обработва дати във формати, които не са в списъка, с някои интересни последици:

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> 

Което демонстрира границите на автоматизирано почистване на данни в лицето на слабите правила за целостта на данните. Заплатата на греха е покварени данни.

@AlexPoole повдига въпроса за използването на 'RR' формат. Този елемент от маската за дата е въведен като Y2K kludge. Доста депресиращо е, че все още го обсъждаме почти две десетилетия в новото хилядолетие.

Както и да е, въпросът е следният. Ако изведем този низ '161225' към дата кой век има? Е, 'yymmdd' ще даде 2016-12-15 . Справедливо, но какво да кажем за '991225' ? Колко вероятно е датата, която наистина искаме, да е 2099-12-15 ? Това е мястото, където 'RR' форматът влиза в игра. По принцип той задава по подразбиране века:числата 00-49 по подразбиране на 20, 50-99 по подразбиране на 19. Този прозорец беше определен от проблема Y2K:през 2000 г. беше по-вероятно '98 отнася се до близкото минало, отколкото до близкото бъдеще и подобна логика се прилага към '02 . Оттук и половината от 1950 г. Обърнете внимание, че това е фиксирана точка не плъзгащ се прозорец. С напредването на 2000 г. тази опорна точка става по-малко полезна. Научете повече.

Както и да е, ключовият момент е, че 'RRRR' не играе добре с други формати за дата:to_date('501212', 'rrrrmmdd') hurls ora-01843:не е валиден месец. So, use 'RR'and test for it before using 'YYYY''. Така че моята преработена функция (с известно подреждане) изглежда така:

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;
/

Ключовият момент остава:има ограничение за това колко умни можем да направим тази функция, когато става въпрос за тълкуване на дати, така че се уверете, че водите най-добре. Ако смятате, че повечето от низовете ви за дата отговарят на ден-месец-година, поставете това на първо място; пак ще получите някои грешни замятания, но по-малко, ако водите с година-месец-ден.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Процедурата на Oracle не връща резултати при изпълнение от задача на скрипт на SSIS

  2. Как да добавя ojdbc7 към уеб приложението на Java от Gradle?

  3. Как да получите достъп до базата данни на Oracle през мрежа?

  4. Премахване на водещи нули от varchar sql developer

  5. Как се свързвате с LDAP сървър с помощта на node-oracledb?