Searching using MySQL: How to escape wildcards

2019-08-01 09:18发布

问题:

I am currently searching my database with a query (using JDBC) like this:

"... AND LCASE(Items.Name) LIKE '%" + searchString.toLowerCase() + "%';"

Now, this is obviously very bad, because it allows for SQL injection as well as insertion of wildcard symbols such as % and _.

My question is, how can I do a query such that even if the searchString contains any of these characters, they will be treated literally?

回答1:

First, don't use LCASE with LIKE unless you're using a case-sensitive locale (which is not the default with MySQL).

As far as escaping those characters, just prefix them with a \ character, so foo%bar becomes foo\%bar.

(It's been a while since I've used Java, but might this work:)

searchString.replaceAll('%', '\\\\%').replaceAll('_', '\\\\_')

(or using a regex):

Regex r = new Regex('(?:%|_)', '\\\\$&');
r.replaceAll(searchString)

As far as preventing SQL injection, just bind the variable as normal:

WHERE LCASE(Items.Name) LIKE ?

And create the bound string like:

'%' + searchString.replaceAll('%', '\\\\%').replaceAll('_', '\\\\_') + '%'


回答2:

According to this, you can escape them using a slash (\) or by specifying your own escape character:

"... AND LCASE(Items.Name) LIKE '%" + searchString.toLowerCase() + "%' ESCAPE '/';"

You'll have to do a search and replace on the mysql LIKE wildcard symbols in your language (Java?), % and _ to replace them with \% and \_ respectively. The other pattern matches you mention above are not (according to the linked docs) supported.