Reputation: 379
I want to insert record in oracle11g database table. I am calling a stored procedure from java. While executing stored procedure I am getting following error.
ORA-01843: not a valid month.
I am converting my date from String to Date in java as follows
date=new SimpleDateFormat("MM/dd/yyyy").parse(visitDate);
In my stored procedure I have following insert query
create or replace PROCEDURE CREATE_VISIT(p_visit_date varchar2)
insert into visit(VISIT_ID,visit_date) values
(frc.SEQ_VISIT.nextval,nvl(to_date(p_visit_date, 'mm/dd/yyyy hh:mi am'),
sysdate));
END CREATE_VISIT;
Upvotes: 0
Views: 1455
Reputation: 231691
You have a String
in Java. You convert that to a Date
in Java. So far, presumably, so good.
Your procedure, however, accepts a varchar2
. So at some point the Date
that you constructed is being explicitly or implicitly cast to a varchar2
. You don't say where that is happening (in Java or in PL/SQL) or whether it is being done explicitly or implicitly. If the conversion is being done implicitly in PL/SQL, then that would use your session's NLS_DATE_FORMAT
which may be different for different sessions in the same database. In a default US-based install of the database and of the client, that would be DD-MON-RR
.
Within your procedure, you then call to_date
on the string that was passed in using an explicit format mask. If the string that is passed in is not in the format mm/dd/yyyy hh:mi am
you'll either get an error or, worse, you'll get an incorrect result (this is the old question of whether the string 01/02/03 represents January 2, 2003 or February 1, 2003 or February 3, 1901).
If we guess that the Date
in Java is being implicitly cast to a varchar2
using your session's default NLS_DATE_FORMAT
of DD-MON-YYYY
, then we can see why your to_date
conversion would fail. If you have a Date
of May 30, 2014, for example, that would be implicitly cast to the string "30-MAY-14". If you then try to cast that back to a date
using to_date
and a format mask of mm/dd/yyyy hh:mi am
, Oracle would try to convert the 30 from your string to a month and raise an error since there is no 30th month.
Realistically, you should be using the proper data type throughout and you should be avoiding implicit casts like the plague. If you declare your procedure to take a date
parameter, then you can pass a Date
from your Java code and omit the to_date
call in your procedure. The Date
will be passed from Java to PL/SQL without needing to be converted to a varchar2
and then converted back to a date
and you won't have to worry about making sure that all your format masks align throughout your code base.
create or replace PROCEDURE CREATE_VISIT(p_visit_date date)
AS
BEGIN
insert into visit(VISIT_ID,visit_date)
values (frc.SEQ_VISIT.nextval,nvl(p_visit_date, sysdate);
END CREATE_VISIT;
Upvotes: 2