I'm having trouble with an SQL query. The problem is that I'm querying an external database of enterprise names and some names are like "Martha's" (include apostrophes). And because I'm querying from an android app, the query string looks like:
String query = "Select * from Advertiser where AdvName= '" + name + "';";
So is there anyway I could ignore or change the apostrophes in the query?
Thanks in advance!
That's one of the reasons why you should always use prepared statements when executing parameterized queries:
String sql = "select * from Advertiser where AdvName = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, name);
ResultSet rs = stmt.executeQuery();
The JDBC driver will escape the quotes for you, and this will also prevent SQL injection attacks.
Prepared statements also have performance advantages when you must execute the same query several times but with different parameters.
Read more about prepared statements in the JDBC tutorial.
Side note: you shouldn't have a ; at the end of your query.
In PLSQL you should use double '' in the input-field, meaning, Martha's => Martha''s:
String query = "Select * from Advertiser where AdvName= 'Martha''s';";
Important Remark:
For security purposes (to avoid sql injection) you should avoid creating queries the way you do, better use prepared-statement and set the parameters like this:
String query = "Select * from Advertiser where AdvName= ? ";
PreparedStatement st = conn.prepareStatement(query);
st.setString(1,name);
Related
query="select * from books where BookName LIKE \"%" +txt1.getText()+"%\"";
this is for mysql server database code.
what will be change for oracle?
DO NOT build SQL queries using string concatenation - you should be using bind parameters.
Your query string should be:
query="select * from books where BookName LIKE ?";
and then you can do something like:
Class.forName( "oracle.jdbc.OracleDriver" ); // If you are using the Oracle driver.
Connection con = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:XE",
"username",
"password"
);
final String query="select * from books where BookName LIKE ?";
PreparedStatement ps = conn.prepareStatement(query);
ps.setString( 1, "%" + txt1.getText() + "%" );
ResultSet rs = ps.executeQuery();
// Loop through the result set.
// Close statement/connections
(you will need to handle exceptions, etc.)
and:
You should not need to change the query to swap between MySQL and Oracle (just change the driver and connection string).
You do not need to escape any single or double quotation marks in the input string.
You are protected from SQL injection attacks.
Oracle can cache the query with the bind parameter and does not have to re-parse / re-compile it when the bind parameter changes.
If you are going to write the query as a string then string literals are surrounded by single quotes (not double quotes) in SQL:
query="select * from books where BookName LIKE '%your_string%'";
and you need to make sure that any single quotes in your string are properly escaped (but just use a bind parameter instead).
problem solved with this..
query="select * from books where BookName LIKE '%" +txt1.getText()+"%'";
thanks everyone :)
I'm tring to write a query but I obtain a syntax error. I know that this error is in the query's syntax. This is the query
ResultSet set=statement.executeQuery("Select * from Ombrellone where PosizioneX='"+c.getX()+"',PosizioneY='"+c.getY()+"'" );
Anyone can help me?
If you want to have multiple conditions on select, you must use AND, not comma.
ResultSet set=statement.executeQuery("Select * from Ombrellone where PosizioneX='"+c.getX()+"' and PosizioneY='"+c.getY()+"'" );
Side note : Avoid using String concatination with query parameters. They causes SQL injections and try using PreparedStatement.
Though the problem in your case was basically because you used comma on your SQL query which is wrong you can use AND or OR for condition fulfillment when using WHERE clause but also
I would suggest you to use PreparedStatement over Statement.
String query = "Select * from Ombrellone where PosizioneX = ? and PosizioneY = ?"
PreparedStatement statement = conn.prepareStatement(query);
statement.setString(1,c.getX());
statement.setString(2,c.getY());
ResultSet resultSet = statement.executeQuery();
Refer difference between statement and preparedstatement
I am trying to write a very simply query using the PreparedStatement class. I read here:Fail to convert to internal representation JDBC that you cannot parameterize column names, only values. Since my query is very simple, the only 'value' I can parameterize is count (*).
This is the query:
SELECT COUNT (*) FROM EZ_DAY
If I try to parameterize it like this:
SELECT ? FROM EZ_DAY
I get an error:
Fail to convert to internal representation
when using the method getInt() on the ResultSet.
How can I use PreparedStatement and parameterize something in this query to prevent SQL injection? Also I know you can't parameterize column names, does that include table names? For example, can I do something like:
SELECT COUNT (*) FROM ?
?
That query cannot fall into SQL injection. The queries that fall in this category are those queries that you build by plain String concatenation. For example:
String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colX = " + stringParameter;
Statement stmt = con.createStatement(query);
ResultSet rs = stmt.executeQuery();
In your case, there's no parameter to inject, so there's no way to have a SQL injection attack for your specific case.
If you need to prevent from SQL injection attacks, use PreparedStatement and do not concatenate the query. Instead, pass the parameters through the interface, which will escape any invalid character for you:
String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colX = ?";
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1, stringParameter);
ResultSet rs = pstmt.executeQuery();
In case you need to build a dynamic query, then you may fall back into concatenating strings, regardless if you use plain String concatenation or a StringBuilder:
//Common solution, still suffers from SQL injection
String query = "SELECT COUNT(*) FROM EZ_DAY WHERE 1 = 1 ";
if (stringParameter != null) {
query = query + = "AND colX = " + stringParameter;
}
Instead, it is better to use a COALESCE or IFNULL function to the parameter to avoid such situations:
//Better solution
String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colx = COALESCE(?, colx)";
In the case above:
If the parameter has a different value than null, the query would be like this:
String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colx = ?";
If the parameter has null value, then the query would be like this:
String query = "SELECT COUNT(*) FROM EZ_DAY WHERE colx = colx";
In the last example, you're still able to use PreparedStatement and avoid SQL injection attacks.
Related:
Difference between Statement and PreparedStatement
As explained in this post, SQL injection can lead to very serious issues like:
call a sleep function so that all your database connections will be busy, therefore making your application unavailable
extracting sensitive data from the DB
bypassing the user authentication
And it's not just SQL that can be affected. Even JPQL can be compromised if you are not using bind parameters.
Bottom line, you should never use string concatenation when building SQL statements. Use a dedicated API for that purpose:
JPA Criteria API
jOOQ
I'm trying to connect netbeans to my postgresql database. The connection seems to have worked as I don't get any errors or exceptions when just connecting, methods such as getCatalog() also return the correct answers.
But when I try to run a simple SQL statement I get the error "ERROR: relation "TABLE_NAME" does not exist", where TABLE_NAME is any one of my tables which DO exist in the database. Here's my code:
Statement stmt = con.createStatement();
ResultSet rs;
String query = "SELECT * FROM clients";
rs = stmt.executeQuery(query);
I was thinking that netbeans might not be finding the tables because it's not looking in the default schema (public), is there a way of setting the schema in java?
EDIT: My connection code. The database name is Cinemax, when I leave out the statement code, I get no errors.
String url = "jdbc:postgresql://localhost:5432/Cinemax";
try{
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException cnfe) {
System.err.println("Couldn't find driver class:");
cnfe.printStackTrace();
}
Connection con = DriverManager.getConnection( url,"postgres","desertrose147");
I suspect you created the table using double quotes using e.g. "Clients" or some other combination of upper/lowercase characters and therefor the table name is case sensitive now.
What does the statement
SELECT table_schema, table_name
FROM information_schema.tables
WHERE lower(table_name) = 'clients'
return?
If the table name that is returned is not lowercase you have to use double quotes when referring to it, something like this:
String query = "SELECT * FROM \"Clients\"";
You could check these possibilities:
String query = "SELECT * FROM clients";
String query = "SELECT * FROM CLIENTS";
String query = "SELECT * FROM \"clients\"";
String query = "SELECT * FROM \"CLIENTS\"";
String query = "SELECT * FROM Clients";
Maybe one of those would work.
Besides CoolBeans' suggestion, you may also be connecting to the db as a different user who does not have permission on the relevant db or schema. Can you show the connection string?
Funny thing is i was experiencing the same thing as i had just started on netbeans and postgressql db, and the error was fixed after noting that the issue was that my tables in postgressql had capital letters in my naming convention which me and my jdbc query statement for INSERT was failing to find the table. But after renaming my tables in the db and fixing the column names as well am good to go. Hope it helps.
Could someone please give me a link on how to create a query in JDBC that gets a variable name in the WHERE statement, or write an example, to be more specific, my code looks something like this:
private String getLastModified(String url) {
String lastModified = null;
ResultSet resultSet;
String query = "select LastModified from CacheTable where " +
" URL.equals(url)";
try {
resultSet = sqlStatement.executeQuery(query);
}
Now I need the syntax that enables me to return a ResultSet object where URL in the cacheTable equals url from the method's argument.
thanks
The easiest way would be
String query = "select LastModified from CacheTable where url = '" + url +"'";
You should use bind variables though:
String query = "select LastModified from CacheTable where url = ?";
prepStmt = conn.prepareStatement(query);
prepStmt.setString(1, url);
rs = prepStmt.executeQuery();
To take it one step further you should really use DBUtils from apache-commons or Sping JDBC framework. A lot of JDBC work is mundane and error prone due to the number of steps involved with it. Both links have working examples for you to get started.
These helper libraries will make your life much more comfortable :-).
To clear a misconception: JDBC and SQL are two entirely different things. Databases only understand the SQL language. It's a (semi)standard which you can learn here. JDBC is just a Java API which enables you to execute SQL language using Java code. Nothing less, nothing more. JDBC is not a Java way of writing SQL language or so. It's just the messenger between Java code and the database. You can learn JDBC here.
That said, yes, the PreparedStatement is the way to go to set values in a SQL query. It not only eases setting fullworthy Java objects in a SQL string using the setXXX() methods, but it also saves you from SQL injection attacks.