JdbcTemplate problems with nested queries - java

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.

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'))";

Spring JDBCTemplate throwing BadSqlGrammarException

I have an SQL query that is executed using Spring JDBCTemplate to retrieve data from an Oracle DB. While executing the statement, org.springframework.jdbc.BadSqlGrammarException is thrown.
The same SQL statement returns proper results when run in the SQL Plus console.
Below is the code that I am trying to execute:
String query = "SELECT DISTINCT O.ORGID FROM ORGANISATIONS O WHERE O.ORGTYPE NOT IN ('P','G') AND O.USERID = 40";
ArrayList<Organisations> orgsList = new ArrayList<Organisations>();
Object[] paramsArray = new Object[]{};
orgsList = (ArrayList<Organisations>) getJdbcTemplate().query(query.toString(), paramsArray ,
new RowMapper<Organisations>(){
public MetricsRoleMap mapRow(ResultSet rs, int rowNum) throws SQLException {
// Data retrieval code;
};
});
Here is the error generated:
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [ SELECT DISTINCT O.ORGID FROM ORGANISATIONS O WHERE O.ORGTYPE NOT IN ('P','G') AND O.USERID = 40]; nested exception is java.sql.SQLException: Invalid column name
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231) [spring-jdbc-4.0.5.RELEASE.jar:4.0.5.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) [spring-jdbc-4.0.5.RELEASE.jar:4.0.5.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660) [spring-jdbc-4.0.5.RELEASE.jar:4.0.5.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:695) [spring-jdbc-4.0.5.RELEASE.jar:4.0.5.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:727) [spring-jdbc-4.0.5.RELEASE.jar:4.0.5.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:737) [spring-jdbc-4.0.5.RELEASE.jar:4.0.5.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:787) [spring-jdbc-4.0.5.RELEASE.jar:4.0.5.RELEASE]
Similar code that I wrote for another method works well. I think there is a minor mistake here, but I am unable to find it.

Passing list of IDs to SQL Statement

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

Categories

Resources