Java Prepared statement Sql query error - java

I am trying to run the following statement in a java program.My problem is the first question mark(parameter) in the statement is failing and the error message reads :
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 ''hello' ON SCHEDULE EVERY 1 WEEK STARTS CONCAT(CURRENT_DATE +
INTERVAL 1 - WEEKD' at line 1.
Is there something im missing can i not carry out a statement in this fashion ?
The query worked before i tried to add the first parameter and just added a name manually into the query ,Any help will of course be appreciated.
PreparedStatement ps1 = null;
ps1 = connection.prepareStatement("CREATE EVENT ? ON SCHEDULE EVERY 1 WEEK STARTS CONCAT(CURRENT_DATE + INTERVAL ? - WEEKDAY(CURRENT_DATE) DAY, ? ) "
+ " DO UPDATE tablename SET status = ? WHERE name= ? AND address= ?");

This is because the name hello get quoted since is passed as a parameter, in this case you could remove the parameter and just concatenate the string or just embed into the string :
connection.prepareStatement("CREATE EVENT hello ON SCHEDULE EVERY 1 WEEK STARTS CONCAT(CURRENT_DATE + INTERVAL ? - WEEKDAY(CURRENT_DATE) DAY, ? ) "
+ " DO UPDATE tablename SET status = ? WHERE name= ? AND address= ?");
or going with String format :
connection.prepareStatement(String.format("CREATE EVENT %s ON SCHEDULE EVERY 1 WEEK STARTS CONCAT(CURRENT_DATE + INTERVAL ? - WEEKDAY(CURRENT_DATE) DAY, ? ) "
+ " DO UPDATE tablename SET status = ? WHERE name= ? AND address= ?", hello));

Related

Statement.execute() function return Boolean value

I'm trying to do a very simple thing: know if a row exists in my SQLite DB.
The Statement.execute(sqlquery) function should allow me to do this, as it reads in the description of the function: if the SQL query returns 1 or more rows the return = true, if the SQL query returns 0 rows its return = false.
I don't think is necessary I go deeper into the structure of my DB or my program. I'm doing this quite simple return
System.out.println("1---" + stat1.execute("SELECT EXISTS(SELECT 1 FROM " + TABLA_OFERTAS + " WHERE " + OFERTAS_COL_ID + " = '" + id + "' AND " + OFERTAS_COL_ASIGNADA + " = 'SI')"));
Where id is a variable that iterates through every row of the table. I'm just filtering for every row if it has a column with a YES (that should return a true), if that particular column has another thing the SQL query shouldn't match and it should return no value so it should return a false.
If I use this same select sentence on an external SQL program this actually returns 0 values, but for some reason, while in my own program this System.out ALWAYS returns true.
I've checked the "id" variable and it works fine. I don't know what to do.
Thanks in advance for any help you can provide. Maybe I've misunderstood the method Javadoc. I don't know.
If more info is needed I'm willing to share it.
Your query uses EXISTS which returns 1 if the conditions are satisfied or 0 if not.
So, you get always 1 row.
Moreover, the method execute() always returns true, when the sql statement is a SELECT query.
What you need is to check the result of the query if it returned 1 or 0, but you can do it without EXISTS, with a PreparedStatement and ? placeholders in the sql statement, which is the safe way to pass parameters to a query:
String sql = "SELECT 1 FROM " + TABLA_OFERTAS + " WHERE " + OFERTAS_COL_ID + " = ? AND " + OFERTAS_COL_ASIGNADA + " = 'SI'";
PreparedStatement st = conn.prepareStatement(sql)); // conn is your connection object
st.setInt(1, id);
ResultSet rs = st.executeQuery();
System.out.println("1---" + rs.next());
rs.next() will return true if the query returned at least 1 row, or false if there are no rows.
I assume that id is an integer, but if it is a string change to:
st.setString(1, id);

MySQL query not working in Java

String sqlInsertBeacon = "INSERT INTO `beacon` (zone_id, location) VALUE ('(SELECT id FROM zone WHERE GeographicalID = '" + geometry3 + "')', Point(" + x_coordinate + "," + y_coordinate + "))";
System.out.println("The SQL query is: " + sqlInsertBeacon); // Echo for debugging
int countInserted3 = stmt.executeUpdate(sqlInsertBeacon);
System.out.println(countInserted3 + " records inserted.\n");
When I run the above code, the build is successful but the program stops when it reaches the execute line. I am entering using this sql query to insert data into a mysql database. I am not sure where the error is in my query? Can anyone suggest an alternative way or find the mistake?
The output of the program is this, as you can see the program, stops running after the second line:
The SQL query is: INSERT INTO table
(zone_id, location)
VALUES
((SELECT id FROM zone WHERE GeographicalID = '6311599'), Point(-121.9453802,37.3256131) )
;
BUILD SUCCESSFUL (total time: 6 seconds)
For additional information incase it helps:
The stmt, is created like this:
try (
// Step 1: Allocate a database 'Connection' object
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/adhwere2?useSSL=false", "root", "your_new_password"); // MySQL
// Step 2: Allocate a 'Statement' object in the Connection
Statement stmt = conn.createStatement();) {
and the catch exception is :
} catch (SQLException ex) {
}
Try something like this:
String sqlInsertBeacon = "INSERT INTO `beacon` (zone_id, location)" +
" VALUES ( (SELECT id FROM zone WHERE GeographicalID = '" + geometry3 + "'), Point(" +
x_coordinate + "," + y_coordinate + "))";
Just removed the apostrophes aroung the inner SELECT and replaced VALUE with VALUES...
The problem was because the sub-query was returning more than one result, and printing out a stack trace helped debug this error. Using Limit 1 in the sub query also solved this issue.
please use query according to this syntax:
INSERT INTO table
(column1, column2, ... )
VALUES
(expression1, expression2, ... ),
(expression1, expression2, ... ),
...;
your table name is in single quotes and its VALUES not value mind these small things
Correct INSERT INTO SELECT statement looks like this:
INSERT INTO table2
SELECT * FROM table1
WHERE condition;
And you can use PreparedStatement to set parameters in your query.

Is it possible to call DATE_ADD() in Java and store the value in a temporary date variable?

I have a doubt about adding days to Date in MySQL database.
The following is my code:
res=stat.executeQuery("select st_date from tmp1 where st_date = '"+t1.getText()+"'");
while(res.next())
{
System.out.println(res.getDate(1));
int i=0;
while(i<14)
{
statement.executeUpdate("Insert into datetab values(DATE_ADD('"
+res.getDate("st_date")+"',INTERVAL 1 DAY),'"+tempname+"')");
i=i+1;
}
}
All the updates in datetab table occur, but there is a problem. I will explain the problem with an example. If the date from tmp1 table is 28-12-2000, then after executing the insert query with date_add(), what happens is that 13 new inserts are happening, but all those inserts are "29-12-2000".
If the date from tmp1 table is 28-12-2000 Then after executing the insert query with date_add(), what happens is that 13 new inserts are happening, but all those inserts are "29-12-2000".
Because that is exactly what you are asking for. Your insert statement is:
"Insert into datetab values(DATE_ADD('" + res.getDate("st_date") +
"',INTERVAL 1 DAY),'" + tempname + "')"
Since read.getDate is not changing in the loop, the same value is inserted in every interation.
Instead of "Interval 1 DAY", use "Interval " + i + " Day" should insert different days. Is that what you are looking for?

PreparedStatement with CONTAINS query

I have a query that will need to run 28 000 times in a row, so I thought using a preparedStatement probably is a clever idea.
Here is my query :
String requestWithFirstName = "SELECT SE.ELEMENT_ID, SE.LASTNAME||' '||SE.FIRSTNAME AS ELEMENT, (SCORE(1)+SCORE(2))/2 AS SCORE "
+ "FROM BL_SUSPICIOUS_ELEMENT SE "
+ "WHERE CONTAINS(SE.LASTNAME, 'fuzzy({' || ? || '},' || ? || ',' || ? || ', weight)' , 1)>0 "
+ "AND CONTAINS(SE.FIRSTNAME, 'fuzzy({' || ? || '},' || ? || ',' || ? || ', weight)' , 2)>0 "
+ (type > 0 ? "AND SE.ELEMENT_TYPE_ID = ?" : "")
+ " ORDER BY SCORE DESC";
Everthings worked fine until we realized that the fuzzy methods doesn't perform well for splitted words like 'pikachu is my hero' and it is advised to created, in this case, 4 fuzzy search for 'pikachu' 'is' 'my' 'hero'. Not sure if this is true, but as I will run the query 28 000 times it's a good opportunity to see it in action.
So I tried to modify the query in this manner :
"SELECT A.ELEMENT_ID, A.LASTNAME||' '||A.FIRSTNAME AS AKA, SCORE(1) AS SCORE "
+ "FROM BL_AKA A, BL_SUSPICIOUS_ELEMENT SE "
+ "WHERE CONTAINS(A.LASTNAME, ?, 1)>0 "
+ "AND SE.ELEMENT_ID = A.ELEMENT_ID "
+ (type > 0 ? "AND SE.ELEMENT_TYPE_ID = ?": "")
+ " ORDER BY SCORE DESC";
In this case, ? will be set to :
'fuzzy({Burnham},70,4,weight),fuzzy({Investors},70,4,weight),fuzzy({Trust},70,4,weight)'
The query seems fine, running on sql dev. However, with Java, I get the following error :
ORA-20000: Oracle Text error:
DRG-50900: text query parser error on line 1, column 30
DRG-50920: part of phrase not itself a phrase or equivalence
DRG-50900: text query parser error on line 1, column 30
DRG-50920: part of phrase not itself a phrase or equivalence
Any advice ?
I wonder if this is the same situation as the in statement (impossible to create a select * from pokemon where monster in (?))
Thanks !
When you use a prepared statement in java, it will set the parameter according to the method you use. So
String s = "'fuzzy({Burnham},70,4,weight),fuzzy({Investors},70,4,weight),fuzzy({Trust},70,4,weight)'";
statement.setString(s);
will be escaped again and results in:
'''fuzzy({Burnham},70,4,weight),fuzzy({Investors},70,4,weight),fuzzy({Trust},70,4,weight)'''
Try to set the parameter without the quotes.
You can create an IN (?) statement. But you will have to add a questionmark for every parameter: WHERE monster IN (?,?,?,?,?,?)...

Java Spring JDBC template problem

public List<Weather> getWeather(int cityId, int days) {
logger.info("days: " + days);
return getSimpleJdbcTemplate().query("SELECT weather.id, cities.name, weather.date, weather.degree " +
"FROM weather JOIN cities ON weather.city_id = cities.id " +
"WHERE weather.city_id = ? AND weather.date BETWEEN now()::date AND (now() + '? days')::date",
this.w_mapper, cityId, days);
}
error :
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [SELECT weather.id, cities.name, weather.date, weather.degree FROM weather JOIN cities ON weather.city_id = cities.id WHERE weather.city_id = ? AND weather.date BETWEEN now()::date AND (now() + '? days')::date]; The column index is out of range: 2, number of columns: 1.; nested exception is org.postgresql.util.PSQLException: The column index is out of range: 2, number of columns: 1.
it works with :
public List<Weather> getWeather(int cityId, int days) {
logger.info("days: " + days);
return getSimpleJdbcTemplate().query("SELECT weather.id, cities.name, weather.date, weather.degree " +
"FROM weather JOIN cities ON weather.city_id = cities.id " +
"WHERE weather.city_id = ? AND weather.date = now()::date",
this.w_mapper, cityId);
}
so the problem is when im using two ? marks in my query.
how can i make it work to with 2 ? marks???
The problem is probably in this part:
'? days'
The question mark is inside a literal string and so it is not recognized by the sql parser. You could try to rewrite it using the string concatenation operator, although I'm not 100% sure that is valid syntax in this case.
According to this page on the postgres wiki you should be able to simply omit the string 'days', since adding a date and an integer is interpreted as adding the specified number of days.
BETWEEN now()::date AND now()::date + ?
Rewrite the SQL part
AND weather.date BETWEEN now()::date AND (now() + '? days')::date
as
AND weather.date BETWEEN now()::date AND ?
and set it with a fullworthy java.sql.Date value instead of days.
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, days);
Date endDate = new Date(calendar.getTimeInMillis());
// ...
(once again, it's java.sql.Date, not java.util.Date!)
The error is saying that you only have 1 param (ie a ?) in the first sql statement, but you are passing in two args. Spring doesn't know what to do with the second arg.

Categories