I am trying to insert data into MySQL, and while doing so, was faced with the error where the input has single quotation, therefore breaking my sql insert string.
This is my line of code
String visitorSql = "INSERT INTO visitor" + "(encryptedEmail)" + "VALUES ('" + encryptedEmail.replace("'", "\\'")+"')";
The syntax error is,
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 ''w+8L8%]/ò“VZ(R?cêíµ–ö\')' at line 1
I've encrypted the email for the sake of the privacy. Any other idea how should I code it to escape the quotation?
You have to replace all the single quotes(') with ''(2 single quotes) to escape them.
String visitorSql = "INSERT INTO visitor(COLUMN_NM) VALUES ('" + encryptedEmail.replace("'", "''")+"')";
Related
I'm trying to run an insert or update on a table - the string generated from below works fine when copy pasted into HeidiSQL but throws SQLSyntaxErrorExceptions when run from Java:
Statement statement = con.createStatement();
String escapedXML = EscapeString(billboard.getXml());
String sql = String.format(
"DELIMITER $ \r\nBEGIN NOT ATOMIC\r\n" +
"IF EXISTS(SELECT * FROM billboards where Name='%s') THEN UPDATE billboards SET XML='%s' where Name='%s';\r\n" +
"ELSE insert into billboards(Name, XML, CreatorName) values('%s', '%s', '%s');\r\n" +
"END IF;\r\n" +
"END $\r\n" +
"DELIMITER ;", billboard.getName(), escapedXML, billboard.getName(), billboard.getName(), escapedXML, billboard.getCreatorName());
// Insert or update billboard
statement.execute(sql);
I can't figure out why.
I would recommend using the insert ... ok duplicate key syntax here rather than a code block. This is more efficient, and implements the lockout a single statement, which should avoid the problem you meet when running the query from your php code.
insert into billboards(Name, XML, CreatorName)
values(?, ?, ?)
on duplicate key update set XML = values(XML)
For this to work, you need a unique (or primary key) constraint on column Name.
Also, consider using a parameterized query rather than concatenating variables in your query stringW Escaping is inefficient and does not really make your code safer.
You should have tried NamedParameterStatement with your query to facilitate setting of string parameters and avoid their duplication (using refactored query suggested in GMB's earlier answer):
String sql = "INSERT INTO billboards (Name, XML, CreatorName) VALUES (:name, :xml, :creator) "
+ "ON DUPLICATE KEY UPDATE SET XML = :xml";
NamedParameterStatement statement = new NamedParameterStatement(con, sql);
statement.setString("name", billboard.getName());
statement.setString("xml", EscapeString(billboard.getXml()));
statement.setString("creator", billboard.getCreatorName());
// Insert or update billboard
statement.execute(sql);
The reason that you are getting a syntax error is that DELIMITER is a MySQL client command and not an SQL statement. MySQL commands may not be used in with JDBC.
For more information:
Delimiters in MySQL
I am using eclipse and mySQL for coding, while inserting the values I received the syntax error.
if(!(nameOfConvo.equals(visitorName))){
staffConvo = StringUtils.substringAfter(convo, ": ");
System.out.println("Staff - " + staffConvo);
String staffSql = "INSERT INTO webchatdata" + "(staffConvo)" + "VALUES ('"+ staffConvo+ "')";
myStat.executeUpdate(staffSql);
}
else {
visitorConvo = StringUtils.substringAfter(convo, ": ");
System.out.println("Visitor - " + visitorConvo);
String visitorSql = "INSERT INTO webchatdata" + "(visitorConvo)" + "VALUES ('" +visitorConvo+"')";
myStat.executeUpdate(visitorSql);
}
while in mySQL it is printing out some values, it'll only print halfway and display :
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 in a course that he has interest in, it is likely that he will excel in it. I' at line 1
Inserting other variables into the database were fine like ex.
String timeStampSql = "INSERT INTO conversation" + "(timestamp)" + "VALUES ('" +timeStamp+"')";
myStat.executeUpdate(timeStampSql);
The problem may be with the content you're putting in to SQL.
Assuming the full string might be something like this.. (You have not provided what the actual input is in this case, so I can only assume)
Bob's in a course that he has interest in, it is likely that he will excel in it. I'm writing
Notice that the first and last character are single quotation marks.
This is breaking your sql insert string, because it will close the string when it reads ' in the text.
When you save the string, you need to escape the quotations so the string is not finished incorrectly. Note the backslashes added.
Bob\'s in a course that he has interest in, it is likely that he will excel in it. I\'m writing
I have a html page that allows users to enter specific search terms to query the database I've created. The problem I'm having is that when I pass the string to execute as a sql query, it is not wrapping the query in single quotes which is needed to search for a string match in a sql database. Here is the code I have currently:
//Create a statement for the sql queries
java.sql.Statement stmt = conn.createStatement();
//Get results from queries entered
String result_event_name = request.getParameter("event_name");
//Create query string
String sqlQuery_event = "SELECT event_name FROM event where event_name = " + "\'" + result_event_name + "\'";
//execute query
java.sql.ResultSet rs_event = stmt.executeQuery(sqlQuery_event);`
This is the error I get:
SQLException: ERROR: syntax error at end of input Position: 49
I tried using prepare statement -- returns same error
I tried the query without escaping -- returns same error
I tried with no single quotes -- returns same error
The single quote ' only needs escaping once LIKE '%\'%'
But to query backslash \ you need to double escape to LIKE '%\\\\%'
If you wanted to query backslash+singlequote \' then LIKE '%\\\\\'%'
(with 5 backslashes)
Explanation Source excerpt:
Because MySQL uses C escape syntax in strings (for example, “\n” to
represent a newline character), you must double any “\” that you use
in LIKE strings. For example, to search for “\n”, specify it as “\n”.
To search for “\”, specify it as “\”; this is because the backslashes
are stripped once by the parser and again when the pattern match is
made, leaving a single backslash to be matched against.
Credit goes to xchiltonx
Resource Link:
mysql - How to handle query search with special characters /(forward slash) and \(backslash)
I have a bean class which does maintain user data:
soppose I have created a postgresql DB table like this:
StringBuffer sqlStr = new StringBuffer();
sqlStr.append("CREATE TABLE Users ("
user_id bigint,
username character varying NOT NULL,
biography character varying NOT NULL
);
& I want to make a query command and inject my String data inside it:
sqlStr.append("INSERT INTO users(" +
"user_id, username, biography)" +
"\n\tVALUES (" + user.getID()+ "," + user.getUsername() + "," + user.getBiography()+");";
my problem is for example if the data coming from my method has quote or double quote or "," my command will become wrong suppose that the user biography is something like this :
hello, I'm Mr X an "IT Pro" ...
If I run my application and save the output inside a file called query.sql I can't use it because my query command is wrong because of quote & double quote, something like this:
INSERT INTO users(userid, username, biography)
VALUES(2, 'Mehdi', 'hello, I'm Mr X an "IT Pro" ..');
how Can I fix this problem ?
You should never ever use the above method for constructing SQL queries.
"Why not?" you ask, well; where to start. The classic example is Bobby Tables, the more general problem is SQL injection. This leaves your program open to attack but also to random failure - like the situation you describe.
Now, the solution. Always use PreparedStatement to construct your query. In your example
final String query = "INSERT INTO users(user_id, username, biography) VALUES (?,?,?)";
final PreparedStatement ps = con.prepareStatement(query);
ps.setInt(1, user.getID());
ps.setString(2, user.getUsername());
ps.setString(3, user.getBiography());
ps.executeUpdate();
A much nicer syntax to use with is the the SET syntax rather than the traditional VALUES syntax. The query would then look like
final String query = "INSERT INTO users SET user_id = ?, username = ?, biography = ?";
EDIT
The OP is building a query for a script file, not executing a query in the code.
There is a utility class in Apache Commons Lang, StringEscapeUtils. This has an escapeSql method. Looking at the source code, all this does is escape single quotes with another single quote.
This works if you build your queries with single quotes:
VALUES (" + user.getID()+ ",'" + user.getUsername() + "'...
So the query, once the example value is inserted will go from:
VALUES (10 ,'hello, I'm Mr X an "IT Pro"'...
Will become
VALUES (10 ,'hello, I''m Mr X an "IT Pro"'...
The apostrophe in "I'm" is now escaped and harmless.
Note that you obviously need to escape the values and not the query, so (assuming you have a static import for the class)
VALUES (" + user.getID()+ ",'" + escapeSql(user.getUsername()) + "'...
But does not escape other sql characters, percent signs for example.
This is really a stop-gap measure to make the code work while you come up with a more robust solution. And you should come up with a more robust solution.
Why dont you use PreparedStatement? That will also give you better performance as the SQL will be pre-compiled on DB side.
Or
You can escape the quotes using
String.replaceAll http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#replaceAll(java.lang.String, java.lang.String)
I'm trying to insert values into a SQL database from within Java. This works fine, except for some of the values. Eg, when I insert "foo" it appends null at the start so it becomes "nullfoo". If I insert the same statement in SQL Server Management Studio this doesn't happen.
To be sure: I print the string before inserting it and it reads "foo".
My insert code:
statement.execute("INSERT INTO " + settings.getProperty("table") + " VALUES ('" + value1+ "', '" + value2 + "', '" + value3 + "')");
You're concatenating values into the SQL statement. If any of those references (value1, value2 etc) are null, then those will be converted into the string "null" as part of concatenation.
The correct fix for this is not to change the way you're doing validation - it's to stop putting the values into the SQL statement itself. Use PreparedStatement with parameterized SQL and set parameter values instead.
Benefits:
You won't get "null" inserted any more
You won't be vulnerable to SQL injection attacks any more (you are now)
When inserting non-text data you won't need to worry about problematic conversions (this is particularly relevant for date/time fields)
Your code will be clearer, as you'll be separating the code (SQL) from the data (parameter values)
Your prepared statement query plan can be cached by the server, so it may perform faster
You should use variable binding in your SQL
http://decipherinfosys.wordpress.com/2007/08/29/bind-variables-usage-parameterized-queries-in-sql-server/
It's easier to check for errors.
In your case you are probably adding null+"foo" so you get nullfoo.