Error in SQL update query in JDBC - java

For the command given below, if the variable body_template contains " Abhinav's number", it shows the following error:
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 's number
String sql_command = "Update email_template set body_template='"+body_template+"' WHERE id="+idno;
//body_template, idno are of type String
stmt.executeUpdate(sql_command); //Here stmt is a variable of type statement.
Kindly suggest how should I redesign my query so as to handle such cases. Note: Input can't be changed. The problem is coming due to the inclusion of ' in the input.

Note: Input can't be changed. The problem is coming due to the inclusion of ' in the input.
Best practice is to use PreparedStatement for binding the input values with the query parameters. It manages to escape special characters if any in the input values.
Example:
// body_template, idno are of type String
String sql_command = "Update email_template set body_template=? WHERE id=?";
PreparedStatement pst = con.prepareStatement( sql_command );
pst.setString( 1, body_template );
pst.setString( 2, idno );
int updateResult = pst.executeUpdate();

String sql_command = "Update email_template set body_template=\""+body_template+"\" WHERE id="+idno;
//body_template, idno are of type String
stmt.executeUpdate(sql_command); //Here stmt is a variable of type statement.
if body_template doesn't contain ", then this code would work. obviously if body_template does have it then you run into same problem as before. just make sure body_template only contains one type of quotes

Related

JDBC throws SQLSyntaxErrorException while executing UPDATE query while the query works using MySQL console [duplicate]

This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Having a Column name as Input Parameter of a PreparedStatement
(1 answer)
Closed 1 year ago.
I am writing a student management app and have created a function to update student data-
public static void updateStudent(int id, int input) throws SQLException {
Scanner sc = new Scanner(System.in); //Scanner object
Connection connection = ConnectionSetup.CreateConnection(); //Setting up connection
String updateStatement = "UPDATE student_details SET ? = ? WHERE 's_id' = ?;"; //Initializing query
PreparedStatement pstmt = connection.prepareStatement(updateStatement);
System.out.println("Enter new name: ");
String newName = sc.nextLine();
pstmt.setString(1,"s_name"); //sets first ? to the columnname
pstmt.setString(2,newName); //sets the second ? to new name
pstmt.setString(3, String.valueOf(id)); //sets the third ? to the student ID
pstmt.execute(); //executes the query
All the other CRUD functions work fine, but this one throws the following error after inputting all the info-
Exception in thread "main" java.sql.SQLSyntaxErrorException: 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 ''s_name' = 'Prateek' WHERE 's_id' = '6'' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:371)
at com.Student.manage.StudentFunc.updateStudent(StudentFunc.java:76)
at Start.main(Start.java:58)
I tried printing the finalized query and it has correct syntax and works in the MySQL Console-
SQL Query is: UPDATE student_details SET 's_name' = 'new name' WHERE 's_id' = '6';
What is the bug here? Please help me understand.
You can't use query parameters for column names (or any other identifer, or SQL keywords, etc.). When you use a query parameter, it is interpreted as a constant value. So your UPDATE statement is executed as if you had written it this way:
UPDATE student_details SET 's_name' = 'new name' WHERE 's_id' = '6';
This does not work. You can't use a string constant value as the left hand side of an assignment*. When I test it in my local MySQL client, I get this error:
ERROR 1064 (42000): 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 ''s_name' = 'new name' WHERE 's_id' = '6'' at line 1
The error reports it got confused at 's_name', because a quoted string literal is not valid at that place in an UPDATE statement.
The WHERE clause is also a problem. It's not a syntax error, but it doesn't do what you probably intended.
WHERE 's_id' = '6';
This compares the string value 's_id' to the string value '6', it does not compare the column s_id to a value. Obviously the string 's_id' is not equal to '6', so the condition will always evaluate as false, and no rows will be updated.
* You can't put a constant value on the left hand of an assignment in most other programming languages, either.

How do PostgreeSQL functions return multiple columns and rows to a Java application?

I am trying to get 3 fields from 1 table using a function and I am getting errors:
CREATE OR REPLACE FUNCTION sp_search_test_ui_test_prog_revision(dev TEXT)
RETURNS table (dev_op_test_id BIGINT, test_program_name TEXT, test_program_revision TEXT)
AS $$
BEGIN
RETURN QUERY
SELECT dev_op_test_id, test_program_name, test_program_revision
FROM dev_op_test
WHERE device = dev
ORDER BY dev_op_test_id;
END;
$$ LANGUAGE plpgsql;
The JAVA code is below: (device is a String passed to this method) Is this where the error is?
// Get unique devices from dev_op_test
String sql = " SELECT sp_search_test_ui_test_prog_revision(" + device + ") ";
PreparedStatement statement = pgConn.prepareStatement(sql);
ResultSet rs = statement.executeQuery();
// Clear from previous run
cboTestProgDev.getItems().clear();
while (rs.next()) {
TestProgRev tpr = new TestProgRev();
tpr.setDevOpTestId(rs.getLong(1));
tpr.setTestProgramName(rs.getString(2));
tpr.setTestProgramRevision(rs.getString(3));
testProgs.add(tpr);
cboTestProgDev.getItems().add(tpr.toString());
}
And this is the error I keep getting. Notice it's telling me the column doesn't exist, which is true because that is a value not a column name. Any ideas??? I know it may be something simple, I just can't seem to ding the anwser.
The query you are sending is
SELECT sp_search_test_ui_test_prog_revision(mnf0306aa)
Do you notice the missing single quotes around the string? That is why PostgreSQL interprets it as a column name and complains that the column does not exist.
Composing queries with string concatenation is dangerous, it exposes you to the dangers of SQL injection. If device contains a single quote, your statement would cause an error or worse – a skilled attacker could do anything with your database.
Use the power of prepared statements to avoid that danger:
java.sql.PreparedStatement statement =
pgConn.prepareStatement("SELECT * FROM sp_search_test_ui_test_prog_revision(?)";
statement.setString(1, device);
java.sql.ResultSet rs = statement.executeQuery();

How to get data from DB table between two specific dates(specified by user) by SQL statement?

Here is my code..I got error
"UCanAccess error - net.ucanaccess.jdbc.UcanaccessSQLException: incompatible data type in operation: at following line..
PreparedStatement pStmt = conn.prepareStatement(sql)
public void showCeilingMaterials(Site_Details site_detail)
{
String sql="SELECT SiteName, SUM(PlanTileQuantity), SUM(PlanTilePrice), SUM(PellingQuantity),SUM(PellingPrice), SUM(PowderQuantity),SUM(PowderPrice),SUM(LpattiQuantity),SUM(LpattiPrice),LpattiSize,SUM(CeilingTotalPrice) FROM CeilingMaterials Where SiteName='?' AND Date<='?' AND Date>=?";
try (PreparedStatement pStmt = conn.prepareStatement(sql)) {
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");
java.util.Date parsed = format.parse(site_detail.getStartDate());
java.sql.Date sql_date1 = new java.sql.Date(parsed.getTime());
format.format(sql_date1);
java.util.Date parsed1 = format.parse(site_detail.getEndDate());
java.sql.Date sql_date2 = new java.sql.Date(parsed1.getTime());
format.format(sql_date2);
pStmt.setString(1, site_detail.getSiteName());
pStmt.setDate(2, sql_date1);
pStmt.setDate(2,sql_date2);
ResultSet rs= pStmt.executeQuery();
while(rs.next()){
showCeil.setSiteName(rs.getString("SiteName"));
showCeil.setTileQuantity(rs.getString("PlanTileQuantity"));
showCeil.setTilePrice(rs.getString("PlanTilePrice"));
showCeil.setPellingQuantity(rs.getString("PellingQuantity"));
showCeil.setPellingPrice(rs.getString("PellingPrice"));
showCeil.setLpattiQuantity(rs.getString("LpattiQuantity"));
showCeil.setLpattiPrice(rs.getString("LpattiPrice"));
showCeil.setLpattiSize(rs.getString("LpattiSize"));
showCeil.setPowderQuantity(rs.getString("PowderQuantity"));
showCeil.setPowderPrice(rs.getString("PowderPrice"));
showCeil.setTotalCeilingPrice(rs.getString("CeilingTotalPrice"));
show_ceil_w=new Site_Details_Show_Interface();
show_ceil_w.showGui(showCeil);
}
}
}
The SQL command text for a parameterized query must never include quotes (or other delimiters) around parameter placeholders. You have the following, which is incorrect:
... Where SiteName='?' AND Date<='?' AND Date>=?
Specifically, it is Date<='?' that is causing the error cited in the question, although the error message is slightly different in newer versions of UCanAccess (in this case, v3.0.2):
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::3.0.2 incompatible data types in combination
Instead, you need to have
... Where SiteName=? AND [Date]<=? AND [Date]>=?
[Note that Date is a reserved word (built-in function name) in Access so you should use square brackets around it if you want to refer to a column named Date.]
Once that error is corrected then other errors in your SQL manifest themselves. The next one you will have to address is:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::3.0.2 expression not in aggregate or GROUP BY columns: PUBLIC.CEILINGMATERIALS.SITENAME
because you have included SiteName in your list of columns to be returned, but it is not part of an aggregate function (e.g., MIN(), MAX()) or a GROUP BY clause. You have that same problem with LpattiSize as well.
You also have
pStmt.setDate(2, sql_date1);
pStmt.setDate(2,sql_date2);
where you have assigned a value to parameter #2 twice (so parameter #3 has no value).
Finally, be aware that when you SUM() a column without providing an alias, as in
SELECT ... SUM(PlanTileQuantity), ...
the resulting column will not be named "PlanTileQuantity". UCanAccess will assign it an arbirtary column name like "C1", "C2", etc.. It is always best to explicitly assign an alias, e.g.,
SELECT ... SUM(PlanTileQuantity) AS SumOfPlanTileQuantity, ...

"Escape" Bind Variable ? in JDBC SQL search

So I am coding in Java, using JDBC with SQL to get data from a database. I cannot chnage the data or the column names in the database. Everything worked perfectly until I was told today that another column of the database was needed.
So I tried to add the column name to the select statement, however I get an error:
"java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 2."
Here is the variable and name for the column: String est = "\"Estimates Complete?\"";
So after LOTS of research, it seems that there is something called "Bind Variables" in JDBC and ? happens to be one of them. I keep finding forum posts and answers on how to create Bind Variables, but nothing on how to "Escape" them. I cannot change the value of the Estimates Complete? column, and it is needed for my program.
If I try String est = "Estimates Complete?";, then the error I get is:
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]COUNT field incorrect
Anyone know if it is possible? Thanks.
Edit: Code example:
Statement s = conn.createStatement();
String tableName = "\"Open WRs V2\"", data1 = "\"Project Name\"",est = "Estimates Complete?";
String selTable = "SELECT " + data1 + "," + est+ " FROM " + tableName;
s.execute(selTable);
ResultSet rs = s.getResultSet();
while ((rs.next())) {
String name = (rs.getString(1));
String estimate= rs.getString(2);
System.out.println("test: "+estmate);
}
s.close();
can you replace the ? with chr(63) like in the answer here :
How to avoid ODBC parameterization for the question mark character ? within literals and comments?

SQLException when using a PreparedStatement for Derby DB

I have an SQL query that i am going to run using a PreparedStatement, and it is
UPDATE tbl_HitsCounter SET count = ? WHERE keyid = (SELECT id FROM tbl_HitsMaster WHERE sitename = '?')
Now when i set the 2nd paramater, which is a string value, i am getting a strange SQLException.
preparedStatement.setInt(1, 99);
preparedStatement.setString(2, masterKey);
As the setString() method is executed, i am getting an SQLException
The column position '2' is out of range. The number of columns for this ResultSet is '1'.
I have no idea what this is about, i havent even executed the executeUpdate() method.
There is only one placeholder in your SQL but you are trying to assign a value for the second. Your problem is that you have quoted the second placeholder, your SQL should look more like this:
UPDATE tbl_HitsCounter
SET count = ?
WHERE keyid = (
SELECT id
FROM tbl_HitsMaster
WHERE sitename = ?
)
Note the lack of quotes in sitename = ?. This is a placeholder: ?. This is an SQL question mark string literal: '?'.

Categories