Is there a way in JPA 2.0 to set parameter of a query with special characters? I mean, if I do: query.setParameter(field, "%" + value.toString() + "%");, it takes % as special (wildcard) character? It seems to me it's not true in this case, beacuse my search doesn't work with truncated words...
Can You help me??
If you are using
LIKE :feild
for
query.setParameter(field, "%" + value.toString() + "%");
Then value remains free from the '%' sign. You can try to use % in your query and send value from setParameter() method.
You can also try CreteriaBuilderInterface of JPA.
http://www.objectdb.com/java/jpa/query/jpql/string.
you have to escape the query. try to use "\\%" instead
what ever you pass in as a query parameter that will pass on to query and back to database. So to the choice of escape character of the query parameter will depend on database. Like in mysql it is "\'" for "'" and "\%" for "%" so if I want to send "john's 10% commission" as query parameter to mysql, i will try query.setParameter(field, "john\\'s 10\\% commission"); in your case query.setParameter(field, "\\%" + value.toString() + "\\%"); should work. But check the documentation of the database to find out escape character for special cases.
Related
I am getting quite angry with this, so I seek help from the crowd ;)
What I want to do: We have a Unity learning game which shall implement a login window. The entered credentials are then hashed (the pw is) and sent to the server, who then should check this against a database.
I have the following table:
xy.users_confirms with the following colums:
id username email password hashcode created
Why does my code
String sql = "SELECT " + "xy.users_confirms.password as pwhash, "
+"FROM xy.users_confirms " +"WHERE xy.users_confirms.username = " +"\"userNameToGetHashFor\"";
lead me to the SQLException "Parameter index out of range (1 > number of parameters, which is 0)"
?
Thanks, any input is much appreciated!
Try this:
String parameter = "'"+ strNameToGetHashFor + "'";
String sql = "SELECT " + "xy.users_confirms.password as pwhash, "
+"FROM xy.users_confirms "
+"WHERE xy.users_confirms.username ="+ parameter;
You are using varchar value as a parameter so it's need to be quot like this.'username'. or you can use Stored Procedure.
Personally, I would try getting a working query using the custom query box directly in phpmyadmin. Once you have a working query you can re-write it in java.
And I would try writing the syntax like this into the phpmyadmin query box:
SELECT password as pwhash
FROM xy.users_confirms
WHERE username ='userNameToGetHashFor'
Using the above syntax I don't see anyway your error could persist.
Phpmyadmin screen cap showing custom query box: http://screencast.com/t/9h8anH0Aj
(the 2 empty text boxes in screen cap are just me hiding my database info)
The comma after pwhash is one potential cause:
+ "xy.users_confirms.password as pwhash*!*,*!* "
Depending on the DBMS, you may also need to use single quotes instead of double quotes like this:
+ "'userNameToGetHashFor'";
Also this code is potentially vulnerable to a SQL Injection attack so you may want to make the userNameToGetHashFor a parameter rather than concatenating the string into the SQL statement.
Intuitively, what I want to do is something like this:
Restrictions.ilike("concat(user.firstName, ' ', user.lastName)",
text.toLowerCase() + "%")
However, I know that this won't work, because concat(user.firstName, ' ', user.lastName) is not a property that Hibernate understands, even though this is what I would have typed in a regular SQL statement as part of the where clause.
Is there any easy way to make this where restriction with Hibernate Criteria API, or do I have to fall back on good-old HSQL?
Thanks
One solution is to define fullName property in your User class.
#Formula(value="first_name || ' ' || last_name")
private String fullName;
And then use that filed in Criteria,
criteria.add(Restrictions.ilike("fullName", text.toLowerCase() + "%"));
I'm a little floppy on SQL so the statement may not be 100% accurate.
Obviously, this isn't an ilike but if you want to use SQL, why not use a sqlRestriction instead with a parameter?
Restrictions.sqlRestriction("select * from user where concat(user.firstName, ' ', user.lastName) like ?", text.toLowerCase() + "%", StandardBasicTypes.STRING);
I assume the goal is to be able to make a portable Restriction, in which case, this can sub in for your attempted ilike.
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)
A quick question, I can't find it on the internet, probably I am looking at the wrong "term".
But how do you make a SQL query statement with "if contains"
"SELECT something FROM " + TABLE_NAME + " WHERE name **contains** '*String*'", null);
I know you got these statements: = > < >= <= but what to use for if contains?
You want the LIKE keyword
Depending on the variety of SQL for the wildcard.
...Where name like '%string%'
SQLite uses % for a sequence of 0 or more unspecified characters (like a *), and an underscore _ for any single character
SELECT something FROM table WHERE name LIKE '%spam%'
(percent signs act like asterisks in a "conventional" search, give or take.)
You can get much more complicated with dbms specific functions (eg, here's Oracle's) that can, situationally, add regular expressions and other ways of searching.
As always, watch out for collation issues and case.
you can use LIKE
"SELECT something FROM " + TABLE_NAME + " WHERE name like '%yourstring%'";
refer to: http://www.sqlite.org/lang_expr.html
Instead of "if contains" you can use the "like" statement...
the query will be...
"SELECT something FROM tablename where name like %'string'%"
This will return what u want,,,
For Example:
Your table name "abc" contains Jarry,Jack,John,Josh,.....
if u run the query
select * from abc where name like %Ja%
it will return
Jarry,Jack..
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.