How to correct bad sql grammar when passing data? - sql

This is my JDBC file with a the following sql query:
private static final String UPDATE_QUESTION = "UPDATE Quiz SET type=?, questionIndex=?, choiceNum=?, question=?, choiceA=?, choiceB=?, choiceC=?, choiceD=?, correct=?, hint=? WHERE type=? AND questionIndex=?";
When I try and pass some data into the query above in JSON format:
{
"id": 84,
"type":"epidemics",
"questionIndex": 1,
"choiceNum":2,
"question":"updated question3",
"choiceA": "no3",
"choiceB":"yes2",
"choiceC":"no3",
"choiceD":"yes4",
"correct":"no3",
"hint":"second answer"
}
I am getting the following error message:
"timestamp": "2022-11-26T11:52:16.431+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [UPDATE Quiz SET type=?, questionIndex=?, choiceNum=?, question=?, choiceA=?, choiceB=?, choiceC=?, choiceD=?, correct=?, hint=? WHERE (type=?) AND (questionIndex=?)]; nested exception is java.sql.SQLException: No value specified for parameter 12
Any ideas where I'm going wrong in the query?

Note that you need to pass a value for each ? placeholder, even if the same column appears more than once in the prepared statement. So, you need to bind the value for questionIndex twice. Your Java code should look something like:
String UPDATE_QUESTION = "UPDATE Quiz SET type=?, questionIndex=?, choiceNum=?, question=?, choiceA=?, choiceB=?, choiceC=?, choiceD=?, correct=?, hint=? WHERE type=? AND questionIndex=?";
PreparedStatement ps = conn.prepareStatement(UPDATE_QUESTION);
ps.setString(1, type);
ps.setInt(2, questionIndex); // first setter for questionIndex
ps.setInt(3, choiceNum);
ps.setString(4, question);
ps.setString(5, choiceA);
ps.setString(6, choiceB);
ps.setString(7, choiceC);
ps.setString(8, choiceD);
ps.setString(9, correct);
ps.setString(10, hint);
ps.setString(11, type);
ps.setInt(12, questionIndex); // second setter for questionIndex
int row = ps.executeUpdate();
// rows affected
System.out.println(row);

Related

SQLite Error in statement insert with question mark

Hello I am writing a query to insert values in DB SQLite.
Firstly, I read from my records and searched for two values, for example, then I created a new table and inserted new values in.
My code snippet follows:
try
{
Class.forName("org.sqlite.JDBC");
Connection con=DriverManager.getConnection("jdbc:sqlite:tests.db");
con.setAutoCommit(false);
Statement st=con.createStatement();
st.executeUpdate("delete msearch");
ResultSet res=st.executeQuery("select * from newmobile_details");
Boolean rec=res.next();
if(!rec)
{
JOptionPane.showMessageDialog(null,"لايوجد سجلات");
}
else
{
do
{
String mid=res.getString(1);
String model=res.getString(2);
String name=res.getString(3);
int price=res.getInt(4);
String pcolor=res.getString(5);
String imei=res.getString(6);
java.sql.Date date=res.getDate(7);
String access=res.getString(8);
if(mname.equalsIgnoreCase(name))
{
PreparedStatement prp=con.prepareStatement("insert into msearch values(?,?,?,?,?,?,?,?)");
prp.setString(1,mid);
prp.setString(2,model);
prp.setString(3,name);
prp.setInt(4,price);
prp.setString(5,pcolor);
prp.setString(6,imei);
prp.setDate(7,date);
prp.setString(8,access);
prp.executeUpdate();
System.out.println("iam inside2");
rows++;
b=1;
jTextField2.setText("");
}
}while(res.next());
if(b==0)
{
JOptionPane.showMessageDialog(null,"لم يتم العثور على الموبايل ");
jTextField2.setText("");
}
}
con.commit();
con.close();
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null,"The error is1:" +e);
}
I get only exception as below:
The error is1 :sql error or missing database in msearch syntax error
Larry makes a good point and looking at your code more carefully I believe the problem is with the statement
st.executeUpdate("delete msearch");
It seems to be saying you should be qualifying msearch with a database name.
This is the syntax for an insert statement
INSERT INTO TABLE_NAME (c1, c2, c3,...cN)
VALUES (v1, v2, v3,...vN);
You give a list of column names and a list of values.
You don't have the list of column names.
This can't work.

Spring Transient Data Access Resource Exception in jdbcTemplate update

I have a method to detect duplicate entry for a column:
(I inject to jdbcTemplate correctly)
private boolean isDuplicate(String username) {
String sql = " select username from users where username=?";
int result = jdbcTemplate.update(sql, new Object[]{username}, String.class);
return result;
}
But i got this exception in runtime:
org.springframework.dao.TransientDataAccessResourceException:
PreparedStatementCallback; SQL [ select username from users where username=?]; Invalid argument value: java.lang.ArrayIndexOutOfBoundsException;
nested exception is java.sql.SQLException: Invalid argument value: java.lang.ArrayIndexOutOfBoundsException
We can use the queryForList() method of jdbcTemplate like this:
results = jdbcTemplate.queryForList(sql,new Object[]{username},String.class);
if(results.isEmpty(){
//no duplicate
}
else{
//duplicate
}
Where results is a List<String>.

Groovy shows java.io.NotSerializableException when making prepared statement

When executing the following piece of code:
def xml = new XmlSlurper().parse(url)
title = rss.chanel.title
rss.channel.item.each {
sql.firstRow("SELECT COUNT(*) FROM news WHERE title = ? ", [it.title])
}
I get the following error:
Invalid argument value: java.io.NotSerializableException
What may cause it?
The problem was that it.title was a NodeChild object.
In order to get the serializable text of this object I had to use it.title.text(). It was quite tricky since I could use print it.title successfully

IBM Worklight - Error while using variable in a SQL Adapter query

I am using SQL adapter in worklight where I need to have a variable that I need to use it in the query.
I read here and followed the same. But it`s showing the below error.
Pasted the complete error message on using a variable in the SQL adapter.
[ERROR ] FWLSE0099E: An error occurred while invoking procedure [project Sample]Device/SqlStatementFWLSE0100E: parameters: [project Sample]{
"arr": [
{
"parameters": [
null
],
"preparedStatement": "UPDATE devices SET DeviceQuantity=$[count] WHERE DeviceNames = 'DellTestLap';"
}
]
}
Parameter index out of range (1 > number of parameters, which is 0)..
Performed query:
UPDATE devices SET DeviceQuantity=$[count] WHERE DeviceNames = 'DellTestLap';
FWLSE0101E: Caused by: [project Sample]java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
com.worklight.common.log.filters.ErrorFilter
Project.js
function UpdateDeviceDetails(){
var count = 2;
var invocationData2 = {
adapter : 'Device', // adapter name
procedure : 'UpdateDeviceDetails', // procedure name
parameters : [count]
};
WL.Client.invokeProcedure(invocationData2,{
onSuccess : QuerySuccess,
onFailure : QueryFailure
});
}
Adapter.js
var DeviceDetails = WL.Server.createSQLStatement("UPDATE devices SET DeviceQuantity=$[count] WHERE DeviceNames = 'DellTestLap';");
function UpdateDeviceDetails(count) {
return WL.Server.invokeSQLStatement({
preparedStatement :DeviceDetails,
parameters : [count]
});
}
I've never used the $[variable_name] syntax with SQL adapters. I've always used "?"
"UPDATE devices SET DeviceQuantity=? WHERE DeviceNames =
'DellTestLap';"
However, assuming that this syntax does work, how is your code referencing the name "count"? The variable "count" is resolved as the number 2. The SQL statement won't be able to know to reference the name count just by the variable name. It would make more sense if the variable passed to parameters was more like this:
return WL.Server.invokeSQLStatement({
preparedStatement :DeviceDetails,
parameters : [{ count: 2 }]
});
That being said, I've never used this syntax before, I just use the "?" syntax.
You can also use the syntax of ?
var DeviceDetails = WL.Server.createSQLStatement("UPDATE devices SET DeviceQuantity=? WHERE DeviceNames ='DellTestLap';");
this will work surely try it !!!!!!!!!!!!!

How to get a single value back from query vs resultset

I have a JSP file that runs a select statement against an Oracle database.
All the examples I have seen use something like:
Statement st=connection.createStatement();
ResultSet rs=st.executeQuery("Select * from data");
while(rs.next(){
String name=rs.getString("name");
String add=rs.getString("address");
out.println(name+" "+add);
}
I will never have more than one row coming back is there an alternative to ResultSet and a while loop to get at my returning single row of data?
I have used similar kind of thing to validate user login.
String sql = "SELECT * FROM login WHERE username=? AND password=?";
try {
PreparedStatement statement;
statement = connection.prepareStatement(sql);
statement.setString(1, "hardik"); // set input parameter 1
statement.setString(2, "welcome"); // set input parameter 2
ResultSet rs = statement.executeQuery();
if(rs.next()){
// fetch data from resultset
}
}catch(SQLException sqle){
sqle.printStackTrace();
}