error while using delete query in spring mvc - spring

HTTP Status 500 - Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [delete from users where name=sds3]; nested exception is java.sql.SQLException: ORA-00904: "SDS3": invalid identifier

The correct query would be
delete from users where name = 'sds3'
Note the quotes around the string value.
You need to learn using prepared statements, which would avoid that bug, work fine even if the value contains a quote, and prevent SQL injection attacks:
PreparedStatement stmt = connection.prepareStatement(
"delete from users where name = ?");
stmt.setString(1, userName);
stmt.executeUpdate();
Note that the Spring JDBC template does use prepared statements, and that NamedParameterJdbcTemplate also supports named parameters. You should use that.

Related

spring-data-jdbc bad sql grammar on update

In spring-data-jdbc 2.3.2 with 2.6.4 data-jdbc starter. I am seeing the following output. Not clear if this is my error in a model layer or an issue with the framework.
This happens when the root aggregate tries to get updated because of a one-to-many reference modification.
As far as I can tell the SQL spec expects a SET statement here. This is the exception I am getting :
Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [UPDATE "tb_entity" WHERE "tb_entity"."field_id" = ?]; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "WHERE"
Position: 21
Any suggestion is welcome.
Take a look at the foreign table primary key. Even though not strictly necessary to be in consistent state. Anyways, one of the statement of 3NF is that all records in a table must be uniquely identified not matter if they don't represent an entity perse. Data-jdbc uses this key for the relations with List, Set, Map.
https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#jdbc.entity-persistence.types

oracle jdbcTemplate Invalid column type

I am using below code while deleting a row from database
jdbcTemplateObject.update("DELETE FROM SUPERVISION_ROOM cl WHERE cl.fk_group IN ? and cl.fk_room IN ?", gourpIds, deleteExamDTO.getRoomIds());
But i getting following exception:
PreparedStatementCallback; uncategorized SQLException for SQL [DELETE
FROM SUPERVISION_ROOM cl WHERE cl.fk_group IN ? and cl.fk_room IN ?];
SQL state [99999]; error code [17004]; Invalid column type; nested
exception is java.sql.SQLException: Invalid column type] with root
cause
JDBCTemplate does not support a transparent IN list binding as you try to use it.
It is documented in 11.7.3. Passing in lists of values for IN clause
You would have to either have a number of variations with the desired number of place holders prepared or you would have to dynamically generate the SQL string once you know how many place holders are required.
So basically you must first expand the SQL statement with the right number of placeholders and then pass each element as a separate paramater.
...
WHERE cl.fk_group IN (?,?,?,?) and cl.fk_room IN (?,?)

"The statement did not return a result set" on Create table (JDBC) [duplicate]

My original environment is SQL server 2005 + WebSphere v6.0(JDBC 3.0). When I run the program as below and it works well.
ResultSet rs=stmt.executeQuery(sql);
rs.next();
However, when I upgrade the environment to SQL server 2005 + WebSphere v8.5(JDBC 4.0), I get the error message:
com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not
return a result set.
From this forum's information, it seems that I have multiple resultsets, so I try to change the program as follows and it works fine.
stmt.execute(sql);
stmt.getMoreResults();
stmt.getMoreResults();
ResultSet rs=stmt.getResultSet();
rs.next();
My questions is that is there any approach that I can keep my program unchanged and works well with JDBC 4.0 driver(WAS v8.5) or any combination like SQL svr 2000 + WAS v8.5, etc.
Please give me any pointer and your recommendation is valuable to me, thank you.
Ann
You are attempting to execute a query that either produces multiple resultsets or that does not produce a resultset (eg UPDATE, INSERT etc) using executeQuery. The Javadoc for this method explicitly says:
Throws: SQLException - if a database access error occurs, this method is called on a closed Statement, the given SQL statement produces anything other than a single ResultSet object
You either need to use the executeUpdate method (if it is actually an update/insert/delete, or execute and then use the resulting boolean and that of getMoreResults() to decide how to proceed.

Spring->Oracle stored procedure call schema issues

As part of a refactor, I am trying to change database calls to use Spring 4.1.0.RELEASE in order to handle connections and exceptions and allow result sets to be passed between functions and classes.
I've gotten my MS SQL Server stored procedure calls working fine, but when I tried to execute an Oracle stored procedure, I got the following error message:
2014-11-13 15:39:35,836 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /EmailServiceLayer/EmailServletClient/springtest/123:
org.jboss.resteasy.spi.UnhandledException: org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback;
bad SQL grammar [{call SPRING_JDBC_TEMPLATE_TEST()}]; nested exception is java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00201: identifier 'SPRING_JDBC_TEMPLATE_TEST' must be declared
I simplified the problem by writing a couple very simple stored procedures that write to a test table: one that takes a parameter and writes and one that takes no parameters and just writes a hardcoded value. These procedures are in the INV schema, which is the same user that my datasource is configured to use.
Eventually I tried running it on my own personal schema, using a datasource configured to use my personal credentials, and it succeeded. I had an admin grant execute all on the procedures in INV, but still no luck. I've confirmed that I can successfully execute simple inline inserts on the INV schema using Spring JdbcTemplate.execute().
My first attempts were using the JdbcTemplate with a CallableStatementCreator of my own definition. I then tried using SimpleJdbcCall, which is what I found out worked on my personal schema. Both ways give the same error message on the INV schema. Here is the code for my latest attempt:
SimpleJdbcCall caller = new SimpleJdbcCall(alex3InvTemplate).withProcedureName("spring_jdbc_template_test");
MapSqlParameterSource paramMap = new MapSqlParameterSource();
paramMap.addValue("p_testval", testval);
Map<String, Object> result = caller.execute(paramMap);
and my test proc:
create or replace
procedure spring_jdbc_template_test
(
p_testval IN number
)
as
begin
insert into jdbc_template_test_table values(p_testval);
commit;
end;
My application is running on a Wildfly 8.0.0.Final server. The datasource configurations for the 2 schemas are exactly the same except for the credentials used to log in. I am able to execute the procedures in INV using the same datasource with a basic JDBC CallableStatement and I've confirmed that I can run them in SQL Developer.
Thanks in advance for any help.
Turns out I made a silly mistake (typo) and was still using an old datasource and thus a different user than INV. Thanks to Dmitry for making me realize this. Still not sure why I'm unable to execute the procedure from a different user using the Spring framework when I was able to do so using a basic JDBC CallableStatement. It works with the INV datasource though and that's a satisfactory solution for me

Type 4 Driver Issue - Multiple SQLs (Compound SQL)

I have a query with multiple calls in the same line(see code below)
The Statement object is automatically created by JDBCTemplate.
The JDBCTemplate is instantiated as new JDBCTemplate() and the datasource is looked up from the weblogic server pool.
class A implements org.springframework.jdbc.core.StatementCallback {
public Object doInStatement(Statement stmt) throws Exception {
String sql = "select * from a where pk = 'test';select * from b where pk = 'test';select * from c where pk = 'test'";
Statement stmt =
ResultSet rs = stmt.executeQuery(sql);
rs = stmt.getResultSet();
...
rs = stmt.getMoreResults();
...
rs = stmt.getMoreResults();
...
}
Using IBM's Type 2 driver, the above worked perfectly fine. We had to change the driver to Oracle's Type 4 JDBC driver and when we did that, the above broke. It does not work anymore and I get the error below:
[DAO.exec] ERROR :
java.sql.SQLException: [OWLS][DB2 JDBC Driver][DB2]ILLEGAL SYMBOL
select * from a where pk ; VALID SYMBOLS ARE BEGIN-OF-STATEMENT
Does anyone know why a Type 4 driver would not support the above? Is there a different delimeter I need to use in the statement, different way to make it work?
Note: THis code worked without any problems with the IBM type 2 JDBC driver, it failed when we switched to Oracle's Type 4 driver.
We use weblogic as the application server and DB2 database.
You need to execute multiple statements separately not compounded into one string. Most drivers will only allow a single statement to be executed. There are only a few drivers which allow multiple statements to be executed in on statement/execute.
In general you should not depend on this behavior, as it is not explicitly defined in the JDBC spec. If you read between the lines of the JDBC spec, then IMHO executing multiple statements in on statement/execute should not be supported at all, but that is debatable.
Why drivers don't support this: some database systems simply don't support preparing, executing and retrieving results of multiple statements in one statement/execute. So to support it, the driver would actually need to jump through all kinds of hoops to get it to work, even though it is not a requirement of JDBC (or IMHO: not allowed by JDBC).
To substantiate my claim that only one statement should be executed in a single statement/execute:
The object used for executing a static SQL statement (from http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html )
In some (uncommon) situations, a single SQL statement may return multiple result sets and/or update counts http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#execute(java.lang.String)
Similarly, the JDBC spec always talks about 'a query' when talking about statements

Resources