well, as long as you fit the domain of simple numbers I described:
"do a quick check to see if it is all numbers, and maybe a decimal in the middle. "
it'll work - hopefully you see what it does! Knowing what it does - you would be able to answer the question "will it work for my data"
case when x <> '.' and
nvl(replace(translate(x,'0123456789','000000000'),'0',''),'.') ='.' then
to_number(x) end
translate(x,'0123456789','000000000') - turn all digits into zeros
replace( <of that>, '0', '' ) - remove all zeroes
nvl( <of that>, '.' ) - if everything was a digit, then zero, we have null - make null '.'
case when x <> '.' -- '.' by itself is not a number...
and nvl( <of that>, '.') = '.'
we must have
digits.digits
or
digits
or
.digits
or
digits.
as long as you have only those inputs to be considered (eg: 1e10 is not handled... +1.2 is not, -44 is not - but you could easily add support for +/- obviously...)
...
standard yyyymmdd format.
Any clever SQL that will establish "cleanliness" as in your previous example?
......
is a bit more difficult.
it starts easy enough, but leap years make it nasty, it could be something like:
ops$tkyte%ORA10GR2> select
2 case
3 when substr( dt, 1, 4 ) between '1900' and '2100'
4 then case when substr( dt, 5, 2 ) between '01' and '12'
5 then case
6 when (
7 (substr( dt, 5, 2 ) in ('01','03','05','07','08','10','12') and substr( dt, 7, 2 ) between '01' and '31')
8 or
9 (substr( dt, 5, 2 ) in ('04','06','09','11') and substr( dt, 7, 2 ) between '01' and '31')
10 or
11 (substr( dt, 5, 2 ) = '02' and substr( dt, 7, 2 ) between '01' and '28')
12 )
13 then to_date( dt, 'yyyymmdd' )
14 when (substr( dt, 5, 2 ) = '02' and substr( dt, 7, 2 ) = '29' and
15 (
16 (trunc(to_number(substr(dt,1,4))/4) = to_number(substr(dt,1,4))/4 and NOT trunc(to_number(substr(dt,1,4))/100) = to_number(substr(dt,1,4))/100)
17 or
18 (trunc(to_number(substr(dt,1,4))/400) = to_number(substr(dt,1,4))/400)
19 )
20 )
21 then to_date( dt, 'yyyymmdd' )
22 end
23 end
24 end
25 from (select '20400229' dt from dual )
26 /
CASEWHENSUBSTR(DT,1,
--------------------
29-feb-2040 00:00:00
using the rule:
1. The year is a Leap Year if the year is divisible by 4
UNLESS
2. The year is divisible by 100 then it is not a Leap Year (the century rule)
UNLESS
3. the year is divisible by 400 then it is a Leap Year