str_to_date mysql does not run in hsql - java

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.

Related

How to set parameter for mysql event name in JpaRepository?

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?

Avoid duplicates in INSERT INTO in the same table

I have a program in JAVA which creates a table in a database and then I insert rows in this table.
The table is created as below:
String sql = "CREATE TABLE IF NOT EXISTS weather (\n"
+ " city string,\n"
+ " temp real,\n"
+ " feels_like real,\n"
+ " temp_min real,\n"
+ " temp_max real,\n"
+ " pressure integer,\n"
+ " humidity integer\n"
+ ");";
When I add rows, I don't want to have duplicates for the field named "city".
So, for example, if I already have London with its data, I don't want to add it again, even though that all its data may have changed. I want to have it only once in my table.
I have this query for insertion :
String sql = "INSERT INTO weather VALUES(?,?,?,?,?,?,?);";
and I want to modify it so I don't insert city duplicates.
Can anyone help me please? Thanks!
If the version of SQLite you use is 3.24.0+ and there is a unique constraint for the column city, you can use upsert which gives you an option to do NOTHING or UPDATE the table if a unique constraint violation occurs.
In this case:
String sql =
"INSERT INTO weather VALUES(?,?,?,?,?,?,?) " +
"ON CONFLICT DO NOTHING";
if you try to insert a row with an existing city, the statement will fail without an error.
But if the new row contains up to date data for the other columns and you want the row updated, you can do this:
String sql =
"INSERT INTO weather VALUES(?,?,?,?,?,?,?) " +
"ON CONFLICT(city) DO UPDATE SET "
"temp = excluded.temp, " +
"feels_like = excluded.feels_like, " +
"temp_min = excluded.temp_min, " +
"temp_max = excluded.temp_max, " +
"pressure = excluded.pressure, " +
"humidity = excluded.humidity";
and the other 6 columns will be overwritten by the new values you supplied.
If there isn't a unique constraint defined for city and you don't want to or can't define one, then you can avoid inserting the same city twice with NOT EXISTS like this:
String sql =
"INSERT INTO weather SELECT ?,?,?,?,?,?,? " +
"WHERE NOT EXISTS (SELECT 1 FROM weather WHERE city = ?);
In this case you will have to pass in your Java code as an additional 8th parameter the value of the city again.
There is no way to do this in 'effectively standard SQL'*.
But, each individual DB engine does usually have some way of accomplishing this goal.
The concept is called merging or upserting - those are terms you can search the web for. Just search for 'how to postgres upsert' for example. It's called upsert because the more general application is: If some subset of the values I am inserting doesn't exist yet in the DB, INSERT a new row with this data. Otherwise, find the row with the same values for this subset, and then update all the other values with it. For example: "Find the student with ID 12345, and then change the name to 'Joe Bloggs'. If there is no row with that, then make it".
make ALL the values 'the key' and you've reduced your 'insert, ignore if it is already there' to a standard UPSERT.
In psql, you can do ON CONFLICT. searching for 'mysql upsert' gets you to blog posts that give you varying tactics depending on your exact needs, from using INSERT IGNORE (I advice against this, this ignores any and all errors, vs only ignoring the 'already in here' error only), ON DUPLICATE KEY UPDATE (better idea, this), or using REPLACE.
Similar blog posts will be found for any db engine you are using here.
*) Defined not as 'as per some version of the SQL standard', but defined as: 'works in the majority of existing DB engines'.
You can now use on conflict. This requires that you have a unique index/constraint on city but it is already defined as the primary key. Check.
insert into weather ( . . . )
values ( . . . )
on conflict (city) ignore;
SQLite also allows this shorthand:
insert or ignore into weather ( . . . )
values ( . . . );

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 handle Hierarchical Queries(Oracle) through spring data JPA ? where SQL includes START WITH.... CONNECT BY

I am trying to achieving the following things, Link 1, Link 2 using spring data JPA.
I tried many times by unfortunatly I failed each time, so I thought let's ask a question to my friends, may be you guys can help me to get out from this issue.
Actually, I am getting the following an error at every time,
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(SqlExceptionHelper.java:127) [jdbc.spi.SqlExceptionHelper] [main] SQL Error: 17006, SQLState: null
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(SqlExceptionHelper.java:129) [jdbc.spi.SqlExceptionHelper] [main] Invalid column name
My Code in JPA repository is :-
String QUERY = "select * from ( select"
+ " student_id, student_activity_id, student_type_id, LEVEL,"
+ " SYS_CONNECT_BY_PATH(student_id, '/') \"Path\"" + " FROM student"
+ " where student_type_id = 1" + " START WITH student_id = ?1"
+ " connect by NOCYCLE PRIOR student_activity_id = student_id order by level desc"
+ ") a where rownum = 1";
#Query(nativeQuery = true, value = QUERY)
Student getNextStudent(Long parentStudentId);
NOTE - Above mentioned SQL query is perfectly executing in Database.
This is tough to answer without seeing your Student entity and the mappings defined nor the layout of the Student table. Generally I have seen this type of issue if you have mapped more columns in your entity then you are trying to return in your native query. The reason is hibernate will still try to map the other columns that are mapped in your entity but it can't find the column name in the resultset returned by your native query. Check your Entity mapping and the columns that are being returned in your query.

Passing parameter to Cassandra CQL query using DataStax client

I am using datastax as a client for connecting to cassandra. I have successfully connected to cassandra cluster/keyspace/column families through Java. I am trying, firing some queries on cassandra column family thriugh java. For me it is working for simple queries like
ResultSet results = session.execute("select * from demodb.customer where id = 1");
Now I want to take id parameter from user and pass it to session.execute(); statement.
How should I go about it?
Here is a code example of inserting data about an image using a prepared statements.
PreparedStatement statement = getSession().prepare(
"INSERT INTO pixelstore.image " +
"(image_name, " +
" upload_time, " +
" upload_by, " +
" file_type, " +
" file_size" +
") VALUES (?, ?, ?, ?, ?);");
// create the bound statement and initialise it with your prepared statement
BoundStatement boundStatement = new BoundStatement(statement);
session.execute( // this is where the query is executed
boundStatement.bind( // here you are binding the 'boundStatement'
"background", TimeUtil.getTimeUUID(), "lyubent", "png", "130527"));
There have been two recent blog posts on planet cassandra with a demo of what the driver can do, they contain code examples so check them out:
Materialized View with Cassandra and DataStax Java Driver
Small Java Application using DataStax Java Driver and Cassandra 1.2 working
You need to create a prepared statement. Then you need to bind that statement with the ID value you got from the user. Then you can execute the bound statement.

Categories

Resources