How to set parameter for mysql event name in JpaRepository? - java

I want to create MySQL Event programmatically with Query Method (#Query) in spring data. And my code like this:
#Query(value="CREATE EVENT :name ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ON COMPLETION NOT PRESERVE ENABLE"
+ " DO BEGIN"
+ " END", nativeQuery=true)
void createEventTestOpen(#Param("name") String name);
But i get error like this:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
near ''my_sample_name' ON SCHEDULE AT CURRENT_TIMESTAMP +
INTERVAL 30 MINUTE ON ' at line 1
How can I make a MySQL event with using the query method in Spring with variable event name?

Related

str_to_date mysql does not run in hsql

My code is performing the following update at a given time in my mysql database:
" UPDATE client_registration " +
" SET registration_date = NOW() " +
" WHERE cycle <= str_to_date(\"" + now + "\",'%d/%m/%Y %H:%i') ";
However I have a unit test that tries to perform this update on the HSQL database and I receive the following error message: user lacks privilege or object not found: STR_TO_DATE.
Some way to execute the condition WHERE cycle_start <= str_to_date(\"" + now + "\",'%d/%m/%Y %H:%i') for the mysql database and the hsql database?
You have to re-write your query for HSQL:
" UPDATE client_registration " +
" SET registration_date = NOW() " +
" WHERE cycle <= current_timestamp";
How to do "select current_timestamp" in hsqldb?
If you want to run the exact same query on both MySQL and HSQLDB, you need to create the STR_TO_DATE function on HSQLDB. You also need to use the single-quote character in your query: str_to_date('" + now + "','%d/%m/%Y %H:%i') (this quoting follows the SQL Standard).
It is easier if you use the SQL Standard format 'YYYY-MM-DD hh:mm:ss' (e.g '2020-07-21 14:30:00') for your 'now' variable and the format string you use with MySQL. In this case the HSQLDB function is simply created as:
CREATE FUNCTION STR_TO_DATE(STR VARCHAR(30), FORMAT VARCHAR(40) )
RETURNS TIMESTAMP
RETURN CAST(STR AS TIMESTAMP);
Execute the CREATE FUNCTION statement once when you connect to the database and you can use it in all your queries and upade statements.

H2 org.h2.jdbc.JdbcSQLSyntaxErrorException when inserting a Timestamp

A SQL query comparing timestamps works in MySQL, but fails when using an H2 database.
As an example, this is the query that produces the exception:
SELECT * FROM table WHERE time >= '2019-02-01T10:59:12.632Z' AND time <= '2019-04-12T10:59:12.632Z'
The query is created dynamically using Java code, and the timestamps above are of type java.time.Instant.
I have even tried using other types of date/time objects, with the same outcome.
This query executes fine using MySQL, but throws the following error using an H2 DB:
org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement
"SELECT * FROM table WHERE time>= 2019-04-10T13[*]:31:19.498Z AND time <= 2019-04-07T13:31:19.498Z";
SQL statement:
SELECT * FROM table WHERE time >= 2019-04-10T13:31:19.498Z AND time<= 2019-04-07T13:31:19.498Z
I find it puzzling that using colon-separated timestamps cause this issue, especially since the H2 docs use similar timestamps
try converting date string properly
SELECT * FROM table WHERE time >= str_to_date('2019-02-01 10:59:12.632 ', '%Y-%m-%d %T.%f')
AND time <= str_to_date( '2019-04-12 10:59:12.632 ' , '%Y-%m-%d %T.%f')
I am using Spring Boot's JdbcTemplate and creating my queries as follows:
jdbcTemplate.query("SELECT * FROM table WHERE time >= " + startTime + " AND " + " time <= " + endTime, (rs, i) -> Accessor.readFromResultSet(rs));
with the date Strings passed in as Instant objects.
The solution, thanks to #OleV.V's comment, was to pass the date objects in as an Object argument:
jdbcTemplate.query("SELECT * FROM table WHERE time >= ? AND time <= ?", new Object[]{startTime, endTime}, (rs, i) -> Accessor.readFromResultSet(rs));

How to create / call a mysql event from hibernate?

I am using spring , hibernate. I need that when update a status to "A", an event executes after a day.
My question is: How to create the event from Java and?
I have been doing this:
Date endDate = cal.getTime();
Timestamp time = new Timestamp(endDate.getTime());
String sql = "CREATE EVENT EVENT_POLL ON SCHEDULE AT " + time +
" DO UPDATE POLL SET STATUS = 'F' WHERE ID = " + dto.getId();
System.out.println("SQL: " + sql);
springHibernateDao.getSession().createSQLQuery(sql).executeUpdate();
I got this error:
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - No value specified for parameter 1
Please help!
As far as I know this is not possible.
An alternative method is to create an event from the command line in the following structure:
Create an event that runs every minute/hour etc according to what your hibernate code was creating except that this event runs at a regular interval and not just once;
Create a table in which you place your run instruction with the scheduled time it should run;
Use hibernate to insert the instruction into that table;
Let your event check that table and run the code from there.

Mysql function not returning response to Hibernate

I have a mysql function that is being called from a service class of a web application using HibernateCallback class of Spring. This function selects some rows using a cursor, then does some update and insert. It then returns a varchar.
When the rows selected by cursor are few hundreds, everything is fine. But when number of rows was 12000, the calling java code did not receive any response, even for 1 hour.
When we check in mysql slow query log and error log, it shows that mysql function has run in 8 seconds and lock time was 0.7 seconds. But java program is not getting any response. Also, whenever this function is called, mysql process list goes very high.
What could be the possible reason of no response, when as per mysql logs, function has run?
The function is as follows:
CREATE FUNCTION fun_test(
param1 varchar(15),
param2 varchar(20),
v_startTime timestamp,
v_endTime timestamp)
RETURNS varchar(50) DETERMINISTIC
begin
declare v_no_more_rows BOOLEAN;
declare v_id int ;
declare v_count int default 0;
declare v_amount double ;
declare v_totalAmount double default 0;
DECLARE cur1 CURSOR FOR
SELECT id,amount
from table1
where col1=param1
and updatedat>= v_startTime
and updatedat< v_endTime
and amount>0;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET v_no_more_rows = TRUE;
OPEN cur1;
loop_cur1: LOOP
FETCH cur1
INTO v_id,v_amount;
IF v_no_more_rows THEN
CLOSE cur1;
LEAVE loop_cur1;
END IF;
insert into table2 (parentid,createdAt) values(v_id,current_timestamp());
update table1
set updatedat = current_timestamp()
where
id = v_id;
set v_totalAmount=v_totalAmount+v_amount;
set v_count=v_count+1;
END LOOP loop_cur1;
return concat("SUCCESS:",v_totalAmount,":",v_count);
end ;
Edit: Adding mysql slow query log results for this function:
Time: 140116 11:22:39
User#Host: host # [x.x.x.x]
Query_time: 7.868044 Lock_time: 0.852301 Rows_sent: 1 Rows_examined: 0
SET timestamp=1389851559;
select fun_test('a','b','2014-01-01 11:00:00','2014-01-01 12:00:00');

How to cancel a statement with derby?

I have a very long sql statement, with java derby database, and I should want provide to the user a "cancel" things. But I get :
Caused by: java.sql.SQLException: Feature not implemented: cancel.
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
So how can I do something like that with derby ?
Thanks.
Edit 1
There is no next loop in my request ; here is my big sql call:
"DELETE FROM TABLE "
+ "WHERE "
+ "REF_TICKET IN
+ "(SELECT NTICKET FROM OTHER_TABLE WHERE "
+ "REF_OPEN IN
+ (SELECT OPEN FROM AGAIN_ANOTHER_TABLE WHERE "
+ "{fn TIMESTAMPDIFF( SQL_TSI_DAY, TIMECLOSE, CURRENT_DATE)} > 365))");
So it's all in one statement.
It's usually not the ExecuteQuery() call that takes very long, but the ResultSet.next() loop that runs for a long time, fetching all the rows. So just check for the user's cancel request during your row-fetching loop, say, every hundred rows or so.

Categories

Resources