Given a textbox name for example, the user requirement wants to be able to do a wildcard search (such as contains, starts with, ends with).
Is it ok to accept the sql wildcard characters ('%' and '_') as input as long as I am still using parameterized query in the backend (Java)? Effectively, allowing the user to build his own regular expression which is what the user's requirement is all about.
Example:
User types in the
textbox = '%are%'
This parameter is feed to the backend as such:
public class PersonDaoImpl { public List<Person> search(String name){//name gets the value from textbox w/ sql wildcards Query q = mgr.createNativeQuery('select * from Person where name like :name'); //default to always use like since expecting searchkey with sql wildcards q.setParameter('name', name);//gives the input from the screen return q.getResultList(); } }
- The result set woul开发者_StackOverflow中文版d include people with names 'Waren', 'Jared', 'Clare', 'Blare' as expected since user provided a regular expression.
With the SQL Parameterize Query, I can ensure that I won't be allowing SQL Injection. This implements the user requirement for wildcard search, but perhaps does it violate anything that I may have missed?
UPDATES: Just found out that Google allows wildcard too, from their help page.
Well, it violates the fact that the user needs to know (or be told) how to construct SQL "LIKE" syntax, but that's all. You could end up with a slow query this way, in that it won't usually be able to use an index, but I wouldn't be concerned in terms of security or correctness.
It's "safe", but probably not a good idea, for two reasons:
- It's probably not the best ui design to require your users to know sql syntax for this.
- It's horrible for performance: these queries often can't use your indexes, so they are slow to execute. And they require a lot of cpu time to compare all that text, so they add a lot of load (disproportionate to the already high execution time) to your server. You want a solution that relies on a full-text index instead.
I am curious, how does the (OP missed name
parameter end up getting set in the request? What platform is this?setParameter
earlier)
As you noted the user need to know the wild-card syntax i.e. the use of %
, _
, etc. A more popular approach is to just get the string from the username, along with an option for 'exact match'/'starts-with'/'anywhere-in-name'. If you go that route you will also be able to execute a more efficient query in the first two cases.
EDIT:
If the customer insists on contains
query then I think your current approach of requiring the end-user to input a pattern better then converting the input string to pattern by putting %
around it.
This is because the users will still have the option of not adding (or selectively adding) the %
to the search string, resulting in faster query execution. For example:
If the user enter search string
Don
the query isselect ... from ... where name like 'Don'
. The RDBMS will most likely use the index on name.If the user enter search string
Don%
the query isselect ... from ... where name like 'Don%'
. The RDBMS will still quite likely use the index on name.If the user enter search string
%Don
or%Don%
then the index cannot be used.
精彩评论