Passing list of IDs to SQL Statement - java

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});

Related

Unable to solve uncategorized SQLException when calling SQL Server using JDBC

I am using JDBCTemplate to query a SQL server using:
List results = jdbc.query(statement, new ResultDataMapper());
I have tried the statement in PreparedStatementCreator and String formats but neither work. I received the exception below:
SQL state [null]; error code [0]; The statement did not return a result set.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
My sql is:
IF OBJECT_ID('tempdb.dbo.#tempSearch', 'U') IS NOT NULL
DROP TABLE #tempSearch;
CREATE TABLE #tempSearch
(
ID int,
Value VARCHAR(255)
)
INSERT INTO #tempSearch
VALUES(1,'?'),
(2,'?');
with cte as (
select RoleID,','+replace(replace(GroupNames,',',',,'),' ','')+',' GroupNames from UserGroup_Role_Mapping
)
,cte2 as(
select cte.RoleID, replace(cte.GroupNames,','+Value+',','') as GroupNames, s.ID, s.Value
from cte
join #tempSearch s on ID=1
union all
select cte2.RoleID, replace(cte2.GroupNames,','+s.Value+',','') as l, s.ID ,s.Value
from cte2
join #tempSearch s on s.ID=cte2.ID+1
)
SELECT a.Role, a.Sort_Order, a.Parent, a.Parent_ID, a.Parent_URL, a.Child, a.Child_ID,a.Child_URL
FROM NC_View a
WHERE a.Role IN (
Select Name from (
Select distinct RoleID from cte2 where len(GroupNames)=0
) tempRoles
join User_Role
on tempRoles.RoleID = User_Role.ID
)
DROP TABLE #tempSearch
I know the SQL works fine but i just cant get over the hump of calling it from JDBC. I have the Mapper and extractor all done too.
I ran this with a PreparedStatementCreator and String:
when i use PreparedstatementCreator and try to set 2 variables I get index out range errors "com.microsoft.sqlserver.jdbc.SQLServerException: The index 1 is out of range.":
PreparedStatementCreator returnValue = new PreparedStatementCreator() {
#Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
sql.append("("+x +",'" + "?" +"'),"); //when constructing the sql
PreparedStatement statement = con.prepareStatement(sql.toString());
statement.setString(z++, group); //when setting those values
I am not sure why this is? is the syntax incorrect? It seems it is not detecting the set?
from debug i also see:
Unable to translate SQLException with Error code '0'
If I use String straight out i get:
org.springframework.jdbc.UncategorizedSQLException: StatementCallback; uncategorized SQLException for SQL [
SQL FROM ABOVE - I TESTED AND IT WORKS
]; SQL state [null]; error code [0]; The statement did not return a result set.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
I am not sure if the SQL is too complex or what. But also confused how using PreparedStatementCreator it wasnt detecting the ? to set variables... I am running out of ideas. I tried Multiqueries=true too
If I use SET NOCOUNT ON i get a different error:
Unable to solve uncategorized SQLException when calling SQL Server using JDBC
So i am bit confused too. I am not inserting a lot of data so maybe it doesn't matter?
Thanks!

Caused by: java.sql.SQLException: Invalid column index

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});

Calling query having multiple IN Clause from JAVA

This query runs fine from SQL Developer : select * from MYTABLE where (field1, field2) IN (('A', '1'), ('B','2'), ('C','3')) ;
But when I try to call it from java I am getting exception.
public List<MYVO> callDB(List<String> sourceAndIdList) {
System.out.println(sourceAndIdList);
String query = "select * from MYTABLE where (field1, field2) IN (:source_monitorId_list)";
Map<String, List<String>> namedParameters = Collections.singletonMap("source_monitorId_list", sourceAndIdList);
return this.namedParameterJdbcTemplate.query(query , namedParameters, new RowMapper<MYVO>() {
#Override
public MYVO mapRow(ResultSet rs, int rowNum) throws SQLException {
....
}
});
}
One printing my list I am getting : [('A', '1'), ('B', '2'), ('C', '3')]
Exception:
SEVERE: Servlet.service() for servlet [selfservice] in context with
path [/mymonitoring] threw exception [Request processing failed;
nested exception is org.springframework.jdbc.BadSqlGrammarException:
PreparedStatementCallback; bad SQL grammar [select * from MYTABLE
where (field1, field2) IN (?, ?, ?)]; nested exception is
java.sql.SQLSyntaxErrorException: ORA-00920: invalid relational
operator ] with root cause java.sql.SQLSyntaxErrorException:
ORA-00920: invalid relational operator
EDIT: This is not a duplicate as I am looking for a solution with springs NamedParameterJdbcTemplate for a query having multiple IN clause and the size of parameters are known only at runtime.
You can't use bind parameter like this in an "IN".
Either you do :
IN ((:p1, :p2), (:p3,:p4), (:p5,:p6))
But it assumes you know exactly how many items you have (in this case 3) or you "materialize" your parameters in the SQL string:
String query = "select * from MYTABLE where (field1, field2) IN (('A', '1'), ('B', '2'), ('C', '3'))";

JdbcTemplate problems with nested queries

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.

Query using alias on column give an error

When i use alias for column i get error. Without alias everytinig works good. What is the problem with that ? This is simple example, but need to use more aliases in real project to wrap results in some not-entity class, but can't because of this error. How to solve this ?
NOT WORKING (with alias on id column):
public List<Long> findAll(Long ownerId) {
String sql = "select id as myId from products where ownerId = "+ownerId;
SQLQuery query = getSession().createSQLQuery(sql);
return query.list();
}
Error:
WARN [JDBCExceptionReporter:77] : SQL Error: 0, SQLState: S0022 ERROR
[JDBCExceptionReporter:78] : Column 'id' not found.
WORKING (without alias):
public List<Long> findAll(Long ownerId) {
String sql = "select id from products where ownerId = "+ownerId;
SQLQuery query = getSession().createSQLQuery(sql);
return query.list();
}
If your "product" is mapped, hibernate probably don't know about "myId" and therefore can't select it.
You can try something like:
getSession().createSQLQuery(sql).addScalar("myId", Hibernate.LONG)

Categories

Resources