Решение Pure SQL для Oracle 12.2, где удобная опция default null on conversion error
избавляет от необходимости писать функции и обрабатывать исключения:
with demo (date_string) as
( select '2018081' from dual union all
select '01/8/2018' from dual union all
select '01-8-2018' from dual union all
select 'ABCD' from dual union all
select '2018-08-01' from dual union all
select '2018-01-8' from dual union all
select '2017081' from dual union all
select '01-AUG-2018' from dual
)
select t.date_string
, coalesce
( to_date(t.date_string default null on conversion error)
, case sys_context('USERENV','NLS_TERRITORY')
when 'AMERICA' then to_date(t.date_string default null on conversion error,'MM/DD/YYYY')
else to_date(t.date_string default null on conversion error,'DD/MM/YYYY')
end
, to_date(t.date_string default null on conversion error,'DD/MM/YYYY')
, to_date(t.date_string default null on conversion error,'YYYY/MM/DD')
, to_date(t.date_string default null on conversion error,'YYYYMMDD')
, to_date(t.date_string default null on conversion error,'DD/MON/YYYY')
) as converted_date
from demo t
Результаты:
DATE_STRING CONVERTED_DATE
----------- --------------
2018081 01-AUG-2018
01/8/2018 08-JAN-2018
01-8-2018 08-JAN-2018
ABCD
2018-08-01 01-AUG-2018
2018-01-8 08-JAN-2018
2017081 01-AUG-2017
01-AUG-2018 01-AUG-2018
Первый тестне указывает какой-либо формат для использования сеанса по умолчанию (DD-MON-RRRR
и т. д.).
Следующий тест пытается обработать североамериканскую привычку ставить месяц первым.(Я не уверен, что sys_context('USERENV','NLS_TERRITORY') = 'AMERICA'
является надежным тестом, так как он, как правило, является настройкой по умолчанию, независимо от фактической территории. Однако он иллюстрирует, как вы можете ввести некоторую условную логику при желании.)
to_date
довольно прост в отношении символов-разделителей, поэтому я не указал различные форматы для DD-MON-YYYY
против DD/MON/YYYY
и т. Д.