i am attempting to delete one record by passing 2 column as filter using Spring jdbctemplate. But i do not know what is the wrong with below code. I have mentioned exception below. i have checked in dedug, requestId and qtId values are coming.
public void deleteTxn(String sql, int requestId, int qtId) {
try {
jdbcTemplate.update(sql,
new Object[]{
requestId,
qtId
});
} catch(Exception e) {
//
}
}
}
String sql = "DELETE FROM TABLE1 WHERE COL1 = ? AND COL2 = ?";
Exception :
org.springframework.jdbc.InvalidResultSetAccessException:
PreparedStatementCallback; invalid ResultSet access for SQL [DELETE
FROM TABLE1 WHERE COL1 = ? AND COL2 = ?]; nested exception is
java.sql.SQLException: Invalid column index at
org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:235)
at
org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at
org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660)
at
org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:909)
at
org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:970)
at
org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:980)
jdbcTemplate.update has two similar method signatures:
update(java.lang.String sql, java.lang.Object... args)
update(java.lang.String sql, java.lang.Object[] args, int[] argTypes).
In your case the first overloaded method is chosen because you didn't provide int[] argTypes, and hence your update statement has only one argument, which is new Object[]{requestId, qtId}.
The solution is simple: just write jdbcTemplate.update(sql, requestId, qtId);
Or, if you want to provide types, something like this:
jdbcTemplate.update(sql, new Object[]{requestId, qtId},
new int[]{Types.BIGINT, Types.BIGINT});
Related
I'm testing a Dao with an In-Memory DB with H2. I'm passing an int to the query with a map to execute it. This query is working OK on Oracle SQL, but is not succeding in H2.
DAO
#Override
public int deleteCancelled(int days) {
final Map<String, Object> namedParameters = new HashMap<String, Object>();
namedParameters.put(DAYS, days);
namedParameters.put(STATUS, StatusEnum.CANCELLED.toString());
int updated = this.namedParameterJdbcTemplate.update(Query.QUERIES.DELETE_CANCELLED, namedParameters);
return updated;
}
QUERIES
public static final String DELETE_CANCELLED = "DELETE FROM MY_TABLE "
+ "WHERE UPDATE_TS < SYSDATE - :days AND STATUS = :status";
When I try to execute this query on H2, it returns:
Error
org.springframework.jdbc.UncategorizedSQLException:
PreparedStatementCallback; uncategorized SQLException for SQL [DELETE FROM
MY_TABLE WHERE UPDATE_TS < SYSDATE - ? AND STATUS = ?]; SQL state
[HY004]; error code [50004]; Unknown data type : "?"
Unknown data type: "?"; SQL statement:
DELETE FROM MY_TABLE WHERE UPDATE_TS < SYSDATE - ? AND STATUS = ?
[50004-196]; nested exception is org.h2.jdbc.JdbcSQLException: Unknown data
type : "?"
Unknown data type: "?"; SQL statement:
DELETE FROM MY_TABLE WHERE UPDATE_TS < SYSDATE - ? AND STATUS = ?
[50004-196]
I tried to execute the query hardcoding the int in the query (SYSDATE = 4) and it worked, also tried to wrap primitive int into Integer.valueOf(days) and using MapSqlParameterSource to specify which data type is, but none of both worked.
Why is it not working? Anyone knows? Thanks in advance.
EDIT:
StatusEnum
public enum StatusEnum {
CANCELLED("Cancelled"),
CONFIRMED("Confirmed"),
PENDING("Pending"),
SENT("Sent"),
private final String text;
/**
* #param text
*/
private StatusEnum(final String text) {
this.text = text;
}
/* (non-Javadoc)
* #see java.lang.Enum#toString()
*/
#Override
public String toString() {
return text;
}
}
This exception appears to arise because H2 is trying to type-check the statement at compile time and can't uniquely determine the type of the parameter: it could be a date or it could be a number, or perhaps something else.
The workaround (provided in the GitHub issue I raised) is to replace
SYSDATE - ?
with
SYSDATE - CAST(? AS INTEGER)
I've checked this and it works on both H2 and Oracle.
For integer param (Spring data) there is workaround: embrace parameter and add 0:
#Query(value = "DELETE FROM my_table WHERE update_ts < SYSDATE - (:days + 0)")
void cleanup(#Param("days") Integer days);
I'm using namedQuery and this Worked for me. if it can help others.
CAST(:variable AS double)
It must be lowercase to respect hibernate types:
https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#mapping-types-basictypes
the solution of #Luke is working but I had to change to lowercase
I am trying to execute a create query using JDBC. I have a method which creates the query and then I execute it but its showing me syntax error. Below is the stack trace :
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: 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 'supplierId varchar,supplierUrl varchar,totalActivities varchar,activityName varc' at line 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2941)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3243)
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1343)
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1260)
Now the query generated is this :
create table demo ( ID INTEGER PRIMARY KEY AUTO_INCREMENT,supplierName varchar,supplierId varchar,supplierUrl varchar,totalActivities varchar,activityName varchar,activityPrice varchar,tourCode varchar,starRating varchar,totalReviews varchar,geography varchar,duration varchar,category varchar,subCategory varchar);
And below is the method which is generating this query :
private static String getCreateTableQuery(String tableName, String columnData) {
StringBuilder sqlStatement = new StringBuilder("");
sqlStatement.append("create table " + tableName + " ( ID INTEGER PRIMARY KEY AUTO_INCREMENT,");
String[] columns = columnData.split(">"); // columns are separated by >
for (int i = 0; i < columns.length; i++) {
sqlStatement.append(columns[i] + " varchar");
if (i != columns.length - 1) { // no commas after last column
sqlStatement.append(",");
}
}
sqlStatement.append(");");
return sqlStatement.toString();
}
And this is how am executing the query :
SessionImpl sessionImpl = (SessionImpl) getSessionFactory().openSession();
Connection conn = (Connection) sessionImpl.connection();
Statement statement = (Statement) conn.createStatement();
statement.executeUpdate(query);
sessionImpl.close();
conn.close();
Am unable to understand the syntax error. Can someone please explain?
I think you have to pass max length for varchar fields:
Please check this your query will be like that:
create table demo ( ID INTEGER PRIMARY KEY AUTO_INCREMENT,supplierName varchar(255),supplierId varchar(255),supplierUrl varchar(255),totalActivities varchar(255),activityName varchar(255),activityPrice varchar(255),tourCode varchar(255),starRating varchar(255),totalReviews varchar(255),geography varchar(255),duration varchar(255),category varchar(255),subCategory varchar(255));
Here is insert Query:
insert into demo
( supplierName, supplierId, supplierUrl, totalActivities, activityName,
activityPrice, tourCode, starRating, totalReviews, geography, duration,
category, subCategory)
values
(supplierName, supplierId, supplierUrl, totalActivities, activityName,
activityPrice, tourCode, starRating, totalReviews, geography, duration,
category, subCategory)
In Mysql you need to define a length to the varchar. Take a look here:
Why does VARCHAR need length specification?
I don't see a problem with your Java code. Fix your create table statement and you'll probably be fine.
This code:
ids = "1245, 4526, 7689, 8001";
jdbcTemplate.update("DELETE FROM my_table WHERE id IN (?)", new Object[] { ids });
throws the following exception:
(...) nested exception is java.sql.SQLSyntaxErrorException: ORA-01722: invalid number
How do I pass the list of IDs to the above sql statement?
Your query is wrong.You can't pass list to single arguement.
Try this.
jdbcTemplate.update("DELETE FROM my_table WHERE id IN (?,?,?,?)", new Object[] { 1245, 4526, 7689, 8001});
I am new to mysql and I am trying to connect to the database using a Java Program and I am passing a mysql query.
public class dbconnect {
public static void main(String[] args) throws SQLException,ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase?user=root&password=root");
Statement st = conn.createStatement();
int custid= 0;
String myname = null;
String query = "select name from groups where customer_id = 2;";
//This query has a problem can anyone help me fix it.
System.out.println(query);
ResultSet rs1 = st.executeQuery(query);
System.out.println("after query");
while (rs1.next()){
custid = rs1.getInt("customer_id");
myname = rs1.getString("name");
System.out.println(myname);
System.out.println(custid);
}
}
}
I am passing a query "select name from groups where customer_id = 2" .
Here "name" is a coloumn,"groups" is a table and "customer_id" is another column. In the program when I give this query(no typos) I get the following error
Exception in thread "main" java.sql.SQLException: Column 'customer_id' not found.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1144)
at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2815)
at com.memoir.client.widgets.memogen.dbconnect.main(dbconnect.java:61)
I have checked with the table , customer_id is present in the table . They are no spelling mistakes also .Even then it says that customer_id column is not found .
Can anyone help me fix it.
The query needs to be:
String query = "select name, customer_id from groups where customer_id = 2;";
Honestly it doesn't make any sense, your query is
String query = "select name from groups where customer_id = 2;";
and you expect to get customer_id ??
as you are already passing customer_id in where clause you don't need to get it back again from db.
String query = "select customer_id,name from groups where customer_id = 2;";
The above would work with your current code .
You are accessing only name column in query and you are try to get "customer_id" in while loop from result set
while (rs1.next()){
custid = rs1.getInt("customer_id"); // **error is here - remove this line or change your query**
myname = rs1.getString("name");
System.out.println(myname);
System.out.println(custid);
}
Your problem is that you are trying to get an invalid column ("cutomer_id") from the result set which contains only the "name" column.
To resolve this you have to select also the "customer_id" in your query:
"select name, customer_id from groups where customer_id = 2";
custid = rs1.getInt("customer_id");
you result set does not have customer_id
Include that too in your query
try this
String mysqlquery = "select name, customer_id from groups where customer_id=2";
I'm trying to use nested queries with JdbcTemplate but found the issue, it seems to me that it's doesn't suppot nested queries.. Am i right? or what i need to change?
So, i invoke
getJdbcTemplate().query(request, new Object[]{name}...)
// request is query which you can see in error message
which gives results in oracle but failes with
org.springframework.jdbc.InvalidResultSetAccessException: PreparedStatementCallback; invalid ResultSet access for SQL [select sq.name as name from (select t1.name as name from table1 t1 left outer join table2 t2 on t2.id = t1.fk_id where t1.name is not null ) sq where upper(name) like upper('?')]; nested exception is java.sql.SQLException: Invalid column index
EDITED
request is a simple String object which is actually an sql that you see in exception message. The eturn object has no matter in this situation as i left it empty (for testing ourpose)
but just for you to be sure here it is:
List<MyObject> list = getJdbcTemplate().query(request, new Object[]{"Somename"}, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
return new MyObject();
}
});
Try changing the upper('?') to upper(?). By putting the ? in quotes, the database doesn't realize that you're dealing with a parameter.