Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Nikhil.

Asked: April 22, 2016 - 10:50 am UTC

Last updated: May 06, 2016 - 8:16 am UTC

Version: 4.1.1.19

Viewed 10K+ times! This question is

You Asked

If I have varchar datatype column which is populated from the input file . It will include the date values as (21/01/2013 or 20100101 string with any date format) If I have to validate the string format how it can be done .

As my procedure requires the date format as 'MM/DD/YYYY' and if any other format is passed through input file it will update the error description column as invalid date format .

Can you please help me regarding the same ?

Note - I don't want any function created for the same

Thanks in advance..!!!

and Connor said...

"Note - I don't want any function created for the same" - why ? That seems a somewhat nonsensical restriction.

Well, you could use a regular expression to get pretty close:

^(?:(?:(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec))(\/|-|\.)31)\1|(?:(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:(?:0?2|(?:Feb))(\/|-|\.)(?:29)\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$

or if you are loading a table, consider using DML error logging to reject the bad dates. See https://www.youtube.com/watch?v=8WV15BzQIto for an tutorial

Or...do it simply and use a function.

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Nikhil Shetkar, May 05, 2016 - 12:41 pm UTC

Thanks for your help .
Actually In the procedure the date format is validated in the update statement . If the format is different than 'MM/DD/YYYY' then it will update the error description column as invalid date format .

we are not allowed to use function in this case .

Is it possible to use to_Date(column_name,'MM/DD/YYYY') in validation and if date comes in other format then in exception other than block can we update the column as invalid date format ?

If not please provide any other solution.

Thanks in advance
Connor McDonald
May 06, 2016 - 1:43 am UTC

Without a function, you are going to have an enormous list of expressions etc within your SQL. It depends how far you want to go (and its unlikely you'll ever get to a 100% solution, as you would with a function).

You could start with:

case when incoming_date like '__/__/____'

which just checks for the slashes.

Then you head into the digits

case when incoming_date like '__/__/____'
and substr(incoming_date,1,2) between '01' and '12'
and substr(incoming_date,4,2) between '01' and '31'
and substr(incoming_date,7,4) between '1900' and '3000'

but you're still miles off a true valid check (because April 31st is not a valid date).

Then you could check the month/day mappings individually...but now you've got leap years to look out. Then its leap years based on 100 year and 400 year boundaries...

Sure you can do ALL of that in SQL...and you're update statement will be 200 lines long....

... or you can use a function.


Nikhil Shetkar, May 06, 2016 - 5:53 am UTC

yes this can be one of the solution but the update query will look so messed up . :-P

BTW thanks for ur help..!!

I was thinking something like using case statement in update and check for converting date using to_date and handle exception in the case block .

Please correct me if I am wrong .

I know function will make the thing a lot easier but I need to try all the other options before going for a function

lets hope something like this works :-D

this is my first question ever . Feeling nice atleast I am knowing some other things as well about Oracle .

Thanks again :)
Connor McDonald
May 06, 2016 - 8:16 am UTC

"I was thinking something like using case statement in update and check for converting date using to_date and handle exception in the case block ."

There's a name for that ... it's called a function :-)

If you are on 12c, you can have that function defined *inside* the update statement itself


SQL> drop table t purge;

Table dropped.

SQL> create table t ( x varchar2(20), d date , err varchar2(20));

Table created.

SQL>
SQL> insert into t (x) values ('qwe');

1 row created.

SQL> insert into t (x) values ('01/01/2000');

1 row created.

SQL>
SQL> update  /*+ with_plsql */
  2  (
  3  with
  4    function date_checker(p_str varchar2) return date is
  5      dte date;
  6    begin
  7      dte := to_date(p_str,'dd/mm/yyyy');
  8      return dte;
  9    exception
 10      when others then return null;
 11    end;
 12    function date_error_msg(p_str varchar2) return varchar2 is
 13      dte date;
 14    begin
 15      dte := to_date(p_str,'dd/mm/yyyy');
 16      return 'OK';
 17    exception
 18      when others then return 'Fail';
 19    end;
 20  select x,d,err, date_checker(x) valid_date, date_error_msg(x) err_text
 21  from t
 22  )
 23  set d = valid_date, err = err_text;
 24  /

2 rows updated.

SQL>
SQL> select * from t;

X                    D          ERR
-------------------- ---------- --------------------
qwe                             Fail
01/01/2000           2000-01-01 OK

SQL>


but otherwise, you need that function defined separately in the database.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library