Problem with special characters and preparedStatement, ONLY if I use setString - java

I've read many threads regarding this topic, but everybody point to the character set in the database.
I'm using strings with special characters like 'ñ' and I'm not able to set them right in the database. As you may guess, the characters are changed to '?'.
The thing is that using this statement, I get it RIGHT:
stmt = con.prepareStatement("INSERT INTO LONG_CODES_TABLE (TIMESTAMP, TABLE_NAME, CODE__C, CODE_DESC)
VALUES (GET_TIMESTAMP, 'MUNICIPIOS', '" + municipio + "', '" + municipio + "') ");
And just in the same database and table, without changing anything, if I use the following I get the '?' character in the DB:
stmt = con.prepareStatement("INSERT INTO LONG_CODES_TABLE (TIMESTAMP, TABLE_NAME, CODE__C, CODE_DESC)
VALUES (GET_TIMESTAMP, 'MUNICIPIOS', ?, ?) ");
stmt.setString(1, municipio);
stmt.setString(2, municipio);
So, the character problem is happening ONLY if I use setString.
Any ideas?
EDIT: The value of the 'municipio' variable is, for example: 'ABADIÑO'.
Later, I can check the differences between doing it on way or the other by asking for that value with an sql statement, for example:
select * from long_codes_table
where table_name = 'MUNICIPIOS' and code__c = 'ABADIÑO'
One way I get the result row. The other way, I don't.
Thank you.

I had that behaviour, too. On top of that I observed that this error did not occur when the application was started from the IDE. That's how I realized that in the JVM - attributes, the one for the encoding was missing.
java %vm-opts% %clspth% -Dfile.encoding=UTF-8 ...

Related

ExecuteUpdate with possible single quotes

I have the following code:
sql = update [myTable] set content = '" map.getString() + "' where id = " map.getKey();
stmt.executeUpdate(sql);
This is running in a loop, and map.getString() can return a string with single or double quotes in them. I've tried escaping it with multiple quotes around map.getString() (for example
sql = update [myTable] set content = ''" map.getString() + "'' where id = " map.getKey();
But with no luck.
How can I get it to update the content column with the literal value of map.getString()?
Sample error I receive is: (there are many similar ones)
java.sql.SQLException: Incorrect syntax near 's'.
or
java.sql.SQLException: Invalid SQL statement or JDBC escape, terminating ''' not found.
Avoid using concatenate strings of parameter values for building your request:
it is not safe (possible sql injection)
it is not optimized (as the db engine will have always to parse the request even if always the same string is sent to the db)
it will generated lot of bad conversion error (special character etc)
Prefer using PreparedStatement with bind parameters.
Example:
PreparedStatement stmt = connection.prepareStatement("UPDATE mytable SET content = ? WHERE id = ?");
stmt.setString(1, map.getString());
stmt.setInt(2,map.getKey());
stmt.executeUpdate();
Using bind parameters will avoid conversion mistakes and syntax error you are encountering
Use a PreparedStatement. See http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html . They are precomiled, and thus more amenable for executing in loops as well as handling content containing characters which otherwise require special handling.

How do I call a getter from JDBC?

I am executing an update and I want to insert the value that is returned from my getter into the my table.
statement.executeUpdate("INSERT INTO my_table " +
"VALUES(myClass.getValue(), 'abcd',now())");
I have tried debugging through and I found that the String value and datetime executes correctly. However it gives me an exception when I am calling my getter. The detail message that it shows is FUNCTION myClass.getValue does not exist.
My imports are in order. Any ideas?
statement.executeUpdate("INSERT INTO my_table " + "VALUES("+myClass.getValue() + ", 'abcd',now())");
Your get-call was interpreted as a String because of the missing ' " '.
Take a look at prepared statements, they are easy to read and use and you don't have to struggle with these problems.
Prepared Statement Version (also a lot more secure because they are preventing SQL Injection):
PreparedStatement pst = yourconnection.prepareStatement("INSERT INTO my_table VALUES(?,?,now())";
pst.setString(1,myClass.getValue());
pst.setString(2,"abcd");
pst.executeUpdate();
This is the SQL that you're trying to execute.
INSERT INTO my_table VALUES(myClass.getValue(), 'abcd',now())
You need to pass valid SQL to the executeUpdate method in order for it to run. Java won't interpolate variables and method calls inside strings for you. You have to either concatenate their values into the SQL string that you pass to executeUpdate, or use Prepared Statements instead.
You need to make a method call to your myClass object, not a string. The string will not be executed, its not code, just words.
statement.executeUpdate("INSERT INTO my_table VALUES(" + myClass.getValue() + ", 'abcd',now())");
I'm going to show you how to do it with prepared statements since the other answers did not show you:
PreparedStatement prepStmt = con.prepareStatement("INSERT INTO my_table VALUES( ? , 'abcd',now())"));
prepStmt.setString(1, myClass.getValue());
prepStmt.executeUpdate();
Notice the ?. It will get replaced by your Java call to myClass.getValue().
Please do not concatenate SQL strings.

Insert data to sql using java issue

I'm facing an issue with insertion to SQL database from java code.
I'm using INSERT sql query using the java code to enter the data from XML file to SQL database.
You may suppose column named "Description".
Imagine there is a record in XML which contains apostrophe ('). The program crashes due to the error caused by the apostrophe which is included in the data.
I know that manually we can add another apostrophe and make it work, but imagine data of 10.000 records, how can we handle this issue?
Don't do this (string concatenation):
String sql = "insert into MyTable (description) values ('" + value + "')";
Statement st = connection.createStatement();
st.executeUpdate(sql);
Do do this (prepared statement):
PreparedStatement ps = connection.prepareStatement(
"insert into MyTable (description) values (?)"
);
ps.setString(1, value);
pt.executeUpdate();
The value will get correctly escaped for you. Not only does this protect against mishaps like the one you mentioned, it also helps defend you from SQL injection attacks.
Humorous illustration:
Source
You have two options, you should use PreparedStatement and bind your parameter(s). Or, if you really, really, want - you could use StringEscapeUtils.escapeSql(str).

Intermittently getting "sqlexception invalid column index" [duplicate]

I got the following error while testing some code:
SQLException: Invalid column index
What exactly does that mean?
Is there an online document explaining what all the Oracle error codes and statements?
If that's a SQLException thrown by Java, it's most likely because you are trying to get or set a value from a ResultSet, but the index you are using isn't within the range.
For example, you might be trying to get the column at index 3 from the result set, but you only have two columns being returned from the SQL query.
It sounds like you're trying to SELECT a column that doesn't exist.
Perhaps you're trying to ORDER BY a column that doesn't exist?
Any typos in your SQL statement?
Using Spring's SimpleJdbcTemplate, I got it when I tried to do this:
String sqlString = "select pwy_code from approver where university_id = '123'";
List<Map<String, Object>> rows = getSimpleJdbcTemplate().queryForList(sqlString, uniId);
I had an argument to queryForList that didn't correspond to a question mark in the SQL. The first line should have been:
String sqlString = "select pwy_code from approver where university_id = ?";
I also got this type error, problem is wrong usage of parameters to statement like, Let's say you have a query like this
SELECT * FROM EMPLOYE E WHERE E.ID = ?
and for the preparedStatement object (JDBC) if you set the parameters like
preparedStatement.setXXX(1,value);
preparedStatement.setXXX(2,value)
then it results in SQLException: Invalid column index
So, I removed that second parameter setting to prepared statement then problem solved
Just try this fix, as I faced your error:
Remove the single quotation marks around your question mark, which means, if you used your reserved parameters like ('?','?','?') you should make it look like this:
(?,?,?)
I had this problem using a prepared statement. I didn't add enough "?" for the "VALUES" My eclipse had crashed after I did add the proper amount, and lost those changes. But that didn't occur to me to be the error until I started combing through the SQL as p.campbell suggested.
I had the exact same problem when using Spring Security 3.1.0. and Oracle 11G. I was using the following query and getting the invalid column index error:
<security:jdbc-user-service data-source-ref="dataSource"
users-by-username-query="SELECT A.user_name AS username, A.password AS password FROM MB_REG_USER A where A.user_name=lower(?)"
It turns out that I needed to add: "1 as enabled" to the query:
<security:jdbc-user-service data-source-ref="dataSource" users-by-username query="SELECT A.user_name AS username, A.password AS password, 1 as enabled FROM MB_REG_USER A where A.user_name=lower(?)"
Everything worked after that. I believe this could be a bug in the Spring JDBC core package...
the final sql statement is something like:
select col_1 from table_X where col_2 = 'abcd';
i run this inside my SQL IDE and everything is ok.
Next, i try to build this statement with java:
String queryString= "select col_1 from table_X where col_2 = '?';";
PreparedStatement stmt = con.prepareStatement(queryString);
stmt.setString(1, "abcd"); //raises java.sql.SQLException: Invalid column index
Although the sql statement (the first one, ran against the database) contains quotes around string values, and also finishes with a semicolumn, the string that i pass to the PreparedStatement should not contain quotes around the wildcard character ?, nor should it finish with semicolumn.
i just removed the characters that appear on white background
"select col_1 from table_X where col_2 = ' ? ' ; ";
to obtain
"select col_1 from table_X where col_2 = ?";
(i found the solution here: https://coderanch.com/t/424689/databases/java-sql-SQLException-Invalid-column)
I had this problem in one legacy application that create prepared statement dynamically.
String firstName;
StringBuilder query =new StringBuilder("select id, name from employee where country_Code=1");
query.append("and name like '");
query.append(firstName + "' ");
query.append("and ssn=?");
PreparedStatement preparedStatement =new prepareStatement(query.toString());
when it try to set value for ssn, it was giving invalid column index error, and finally found out that it is caused by firstName having ' within; that disturb the syntax.

java sql syntax error insert into

I have problems running this sql statement. It works fine if I run it in mysql but in java I get this 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 '' at line 1
The database has an id(pk) autogenerated, varchar, int, varchar;
Can someone help me?
int i = statement.executeUpdate("INSERT INTO sala values('','"+ nume.getText() + "', "+ Integer.parseInt(capacitate.getText())+ ", '" + sunet.getText()+"'");
Don't just try to fix this code by tweaking the SQL as per adarshr's answer. You have a fundamental security problem here which you should fix right now. You're open to SQL injection attacks due to including user data directly in your SQL.
You should use a PreparedStatement, with the parameters declared as placeholders in the SQL, but then given values separately. Exactly how you'll do that will depend on your JDBC provider, but it'll look something like this:
// TODO: Fix the column names, and close the statement in a try/finally block
PreparedStatement pst = conn.prepareStatement(
"INSERT INTO sala (nume, capacitate, sunet) VALUES (?, ?, ?)");
pst.setString(1, nume.getText());
pst.setInt(2, Integer.parseInt(capacitate.getText()));
pst.setString(3, sunet.getText());
pst.executeUpdate();
Note that if you can get capacite in a way which doesn't require integer parsing, that would be good. Otherwise, consider using NumberFormat which is more locale-friendly. Also note that I've added the column names into the SQL to make this more robust in the face of schema changes.
You haven't closed your query.
int i = statement.executeUpdate("INSERT INTO sala values('','"+ nume.getText() + "', "+ Integer.parseInt(capacitate.getText())+ ", '" + sunet.getText()+"')");
^
But more than all this, you must use PreparedStatement as Jon suggested below.

Categories

Resources