to_date inside callablestatement - java

I'm trying to use a to_date function inside a callableStatement.
My statement ends up being
RGPKG.PKG_RG_LEAD.ADD_LEAD('TO_DATE('05-Aug-2014 11:53:34 AM', 'DD-MON-RR HH.MI.SSXFF AM')',
<More-parameters-here>)
I'm using the following code to build up the TO_DATE function:
CallableStatement stmt
String dateParam = "TO_DATE('" + sTS + "', 'DD-MON-RR HH.MI.SSXFF AM')";
stmt.setString(1, dateParam);
//set more parameters
stmt.execute();
Where sTS is a string in the right date format. I can see that the problem is that the setString is wrapping my string in single quotes, but how do I set this on the callable statement?
create or replace
PACKAGE BODY PKG_RG_LEAD AS
PROCEDURE ADD_LEAD
(p_created_tstamp IN RG_LEAD.CREATED_TSTAMP%type,
p_created_by IN RG_LEAD.CREATED_BY%type,
And the column on the database is created as
CREATED_TSTAMP TIMESTAMP(6) No systimestamp 2

Why don't want to convert your string into date and then send it to your procedure? I have answered similar question already

If you are intent on passing a string into the call, your statement should be:
RGPKG.PKG_RG_LEAD.ADD_LEAD(TO_TIMESTAMP(?, 'DD-MON-RR HH.MI.SSXFF AM'), ?, ...)
Then you can set the value with:
stmt.setString(1, sTS);
You need to_timestamp() rather than to_date() if you want fractional seconds and the XFF part of the format mask, although your sample values doesn't have fractional seconds anyway.
But it would be much better to pass an actual timestamp value, using stmt.setTimestamp() as zaratustra suggests. Here's an example:
String sTS = "05-Aug-2014 11:53:34 AM";
stmt = conn.prepareCall("{ call RGPKG.PKG_RG_LEAD.ADD_LEAD(?, ?, ...) }";
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a");
stmt.setTimestamp(1, new Timestamp(sdf.parse(sTS).getTime()));
...
If your actual value does have fraction seconds then make the format "dd-MMM-yy hh:mm:ss.S a".

Related

Is there a way to use TIMESTAMP_WITH_TIMEZONE as a Function input in Oracle

I am trying to create an Oracle SQL Function which accepts a TIMESTAMP_WITH_TIMEZONE value as an input parameter.
CREATE FUNCTION my_func ( timetz IN TIMESTAMP WITH TIMEZONE ) // Not going to work
// code here
BEGIN
// code here
END;
And then try to pass inputs as below. I am trying to set a different timezone provided by the user as a ZonedDateTime value. In the below code, current LocalDateTime is taken as an example.
public void myFunc( )
{
CallableStatement stmt = con.prepareCall("{call my_func ( ? )}");
stmt.setObject( ZonedDateTime.of( LocalDateTime.now() ), java.sql.Types.TIMESTAMP_WITH_TIMEZONE);
stmt.execute();
}
What would be the ideal way to do this.
Figured out a way to do that. In case, anyone needs help with this question, I will post the work around I used.
Pass the date with timezone as a VARCHAR2 to the Function
CREATE FUNCTION my_func ( timetz IN VARCHAR2 )
// code here
BEGIN
// usage
TO_TIMESTAMP_TZ( timetz, 'YYYY-MM-DD HH24:MI:SS TZR')
END;
Pass the Timestamp with timezone as a String from java
SimepleDateFormatter sdf = new SimpleDateFormatter('yyyy-mm-dd HH:mm:ss')
sdf.format( new Timestamp() ) + " " + "Pacific/US"
stmt.setString( 1, timestampTZString );

Date format in an Oracle stored procedure called from Java

I am trying to use an Oracle stored procedure to update a database table. I am calling the procedure from a Java program. I want my procedure to accept dates in the format '01-01-2015' but for some reason my procedure will only accept a date if it is formatted as '01-JAN-2015'.
My stored procedure:
DELIMITER //
CREATE OR REPLACE PROCEDURE updateAward
(
p_award_id IN awards.award_id%TYPE,
p_award_date IN awards.award_date%TYPE,
p_total_amount IN awards.total_amount%TYPE,
p_number_sales IN awards.number_sales%TYPE,
p_emp_id IN awards.emp_id%TYPE
)
AS
BEGIN
UPDATE awards
SET award_date = to_date(p_award_date, 'DD-MM-YYYY'),
total_amount = p_total_amount,
number_sales = p_number_sales,
emp_id = p_emp_id
WHERE award_id = p_award_id;
COMMIT;
END;
/
The java code that calls it:
public boolean updateByID(Connection conn, String strVar, int[] intVar, double doubleVar)
{
System.out.println(strVar);
System.out.println(doubleVar);
System.out.println(intVar[0]);
System.out.println(intVar[1]);
System.out.println(intVar[2]);
try
{
String query = "{call updateAward(?,?,?,?,?)}";
CallableStatement stmt = conn.prepareCall(query);
stmt.setInt(1,intVar[0]);
stmt.setString(2, strVar);
stmt.setDouble(3, doubleVar);
stmt.setInt(4, intVar[1]);
stmt.setInt(5, intVar[2]);
stmt.executeUpdate();
return true;
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
return false;
}
The console print out of the variables being passed:
12-12-2012
65165.2
21
22
3
The error itself:
KORA-01843: not a valid month
ORA-06512: at line 1
Every solution that I have found has been to put the date format in the procedure. I believe I have done it with
award_date = to_date(p_award_date, 'DD-MM-YYYY'),
Have I written it incorrectly? Can someone please help?
Currently you are passing a String:
stmt.setString(2, strVar);
And you are parsing a String:
award_date = to_date(p_award_date, 'DD-MM-YYYY')
But you are expecting a Date in your custom type, and that is where the conversion fails. Change that to VARCHAR (or VARCHAR2) and it will work.
You're passing a string to a procedure that's expecting an Oracle date argument, via setString(). That means Oracle has to do an implicit conversion of the string to a date as part of the call, using the session/locale NLS_DATE_FORMAT, before you reach your to_date() call.
You could change your procedure argument type from awards.award_date%TYPE to varchar2, and still do the explicit conversion inside the procedure. Or you can leave the procedure signature as it is and pass the correct data type by converting it on the Java side, e.g.:
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
cStmt.setDate(2, new java.sql.Date(sdf.parse(strVar).getTime()));
And as p_date is already a date, you should not call to_date() on that, as it will do an implicit conversion back to a string (using NLS_DATE_FORMAT again) and then try to explicitly convert that back to a date using the format model you supplied, which is also likely to give a similar error. Simplify that to just:
SET award_date = p_award_date,

Retain milliseconds in Oracle DB insert

I am trying to insert a record in a Oracle table using Java. The field in question is defined as a timestamp.
I am using a the following statement:
INSERT INTO MYTAB (UNIQUE_ID, CREATED_AT) VALUES ('137', ?)";
PreparedStatement updatePerf = connection.prepareStatement(updateString);
updatePerf.setTimestamp(1,getCurrentTimeStamp());
The getCurrentTimeStamp looks as follows:
private static java.sql.Timestamp getCurrentTimeStamp() {
long time = System.currentTimeMillis();
java.sql.Timestamp timestamp = new java.sql.Timestamp(time);
System.out.println("Time in milliseconds :" + timestamp);
return timestamp;
}
When the program runs, I still the correct timestamped printed with milliseconds:
Time in milliseconds :2014-05-13 15:40:03.076
However on the database, I only see
'137',2014-05-13 15:40:03
I want to retain the milliseconds desperately.
When you say "on the database, I only see", how are you getting the data out of Oracle? Have you proerly set NLS_TIMESTAMP?
Try setting:
NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH:MI:SS.FF'
in SQL*Plus, and then try the query, and see if you can see thw milliseconds component.
Alternately, you can format the timestamp column w/ a to_char() function:
select to_char(my_timestamp_col,'YYYY-MM-DD HH:MI:SS.FF') from my_table;
Note also, that if your column is timestamp with timezone, you'll need to set NLS_TIMETAMP_TZ_FORMAT instead.

JPA query equivalent to mysql query

Below is mysql query which is working fine and giving me expected results on mysql console.
select * from omni_main as t where t.date_time BETWEEN STR_TO_DATE(CONCAT('2011', '08', '01'),'%Y%m%d') AND LAST_DAY(STR_TO_DATE(CONCAT('2012', '08','01'), '%Y%m%d')) group by year(date_time),month(date_time)
I need its JPA equivalent query. Below is what I am trying but its returning nothing.
String queryStr = "select * from OmniMainEntity o where o.dateTime BETWEEN STR_TO_DATE(CONCAT('"+fromYear+"', '"+fromMonth+"','01'), '%Y%m%d') AND "
+"LAST_DAY(STR_TO_DATE(CONCAT('"+toYear+"', '"+toMonth+"','01'), '%Y%m%d'))";
Query query = manager.createQuery(queryStr);
System.out.println("Result Size: "+query.getResultList().size());
Here fromYear, fromMonth, toYear, toMonth are method parameters using in creating queryStr.
Please suggest where I may wrong!
Any other way to achieve goal is also welcome!
As you are using JPA Query, it would be better to not use database-specified sql function, such as STR_TO_DATE.
You can have a try by this way.(A Hibernate way, JPA should be similiar):
First, you can parse a java.util.Date object from "fromYear" and "fromMonth" like below:
DateFormat df = new SimpleDateFormat("yyyyMMdd");
Date startDate = df.parse(fromYear + "" + fromMonth + "01");
Date endDate = df.parse(.....);
Then, set them into the JPA query.
String queryStr = "select * from OmniMainEntity o where o.dateTime BETWEEN :startDate AND :endDate)"; // The query now changed to database independent
Query query = manager.createQuery(queryStr);
query.setDate("startDate", startDate);
query.setDate("endDate", endDate);
At last, doing the search:
System.out.println("Result Size: "+query.getResultList().size());
Your query doesn't have a verb in it. You probably want SELECT in there:
SELECT o FROM OmniMainEntity o WHERE...
Also, you should be using parameterized and typed queries, and it's usual to use short names (o instead of omniMainEnt) to make your queries readable.

Cant insert an empty date value into mysql

String datum = datumInvoer.getText();
**String bdate = bdatumInvoer.getText();**
String[] speler = spelers.getSelectedItem().toString().split(" ");
String[] toernooi = toernooien.getSelectedItem().toString().split(" ");
try {
PreparedStatement query = con.prepareStatement("INSERT INTO `fullhouse`.`inschrijving_toernooi` ( `IT_datum`, `IT_betaaldatum`, `speler`, `toernooi`) VALUES (?, ?, ? ,?)");
query.setString(1, datum);
query.setString(2, bdatum);
query.setString(3, speler[0]);
query.setString(4, toernooi[0]);
query.execute();
i have set the default to NULL , but it still wont insert it i am close to changing the datatype to varchar.
ERROR: incorrect date value
delimiter $$
CREATE TABLE `inschrijving_toernooi` (
`IT_code` int(11) NOT NULL AUTO_INCREMENT,
`IT_datum` date DEFAULT NULL,
`IT_betaaldatum` date DEFAULT NULL,
`speler` int(11) NOT NULL,
`toernooi` int(11) NOT NULL,
PRIMARY KEY (`IT_code`),
UNIQUE KEY `aaa` (`speler`,`toernooi`),
KEY `FS_code_idx` (`speler`),
KEY `FT_code_idx` (`toernooi`),
First Convert your date parameter from string to date. For that follow code below.
String bdate = bdatumInvoer.getText();
// get the correct date Format
// follow the link to get correct date format
// throws ParseException
Date date = new SimpleDateFormat("dd-MM-yyyy").parse(bdate);
Class SimpleDateFormat API
Now in prepared statement set them as date like shown below. As your table structure allows date in table.
query.setDate(2, date);
Now you still want to set null to that column then you can use and tell your query to set null by using following format in prepared statement.
query.setNull(2, java.sql.Types.DATE);
OR
query.setDate(2, null);
setNull API
Mapping of java.sql.Types to SQL types
I think this will solve your issue.
You need to change how you are passing parameters to you prepared statement
It should be something like below. And datum and bdatum should be of type Date. If you do not use what types are defined in your db you could put pass invalid data to your sql which would cause exceptions.
query.setDate(1, datum);
query.setDate(2, bdatum);
query.setInt(3, speler[0]);
query.setInt(4, toernooi[0]);
I suspect your bdatum variable contains an empty string. If you want to insert a SQL null, you need to pass in null, not empty string. (When I tried this on my machine with a similar insert, I got an "Incorrect date value" when trying to insert an empty string, but not with a null.)
if ("".equals(bdatum))
bdatum = null;
ps.setString(2, bdatum);
When you pass in a string in JDBC for a date value, MySQL will try to parse it, but empty string ("") is not a valid value. This works similarly to if you tried to do an insert with a date literal:
INSERT INTO `some_table` (`some_nullable_date_column`) VALUES ('2000-01-01') -- this works
INSERT INTO `some_table` (`some_nullable_date_column`) VALUES (NULL) -- this works
INSERT INTO `some_table` (`some_nullable_date_column`) VALUES ('') -- this fails
As an aside, passing in a string for a date value is semantically wrong and possibly less robust than parsing the string to a Date object before passing it to the PreparedStatement.

Categories