Reputation: 113
I'm using knex
to generate my SQL queries. In knex
documentation, it shows this
knex('users').where('columnName', 'like', '%rowlikeme%')
Now in my application, I did this:
function search(term) {
term = "%" + term + "%";
knex('table').where('description', 'like', term);
// ...
}
How can I escape %
so that it searches for %
as part of the term as well?
Thanks.
Upvotes: 10
Views: 29176
Reputation: 11
I know this question is 2 years old, but reading the Knex documentation I found out they added a function for this scenario.
knex('users').whereLike('email', '%mail%');
Upvotes: 1
Reputation: 71
For this to resolve you can add the search term in a separate variable and add % at the beginning and end of the string. For ex:
const likeParams = '%' + selectedKeyword + '%';
knex('users').where('title', 'ilike', likeParams);
Upvotes: 0
Reputation: 131
whereILike
http://knexjs.org/guide/query-builder.html#whereilike
This is doc for this
knex('users').whereILike('email', '%mail%')
knex('users')
.whereILike('email', '%MAIL%')
.andWhereILike('email', '%.COM')
.orWhereILike('email', '%NAME%')
Upvotes: 0
Reputation: 203
So I was looking for a correct way to apply LOWER function to the parameter. Here's the solution that seems to be working fine for me:
builder.whereRaw('LOWER(last_name) LIKE LOWER(?)', [`%${lastName}%`])
Upvotes: 5
Reputation: 4829
@coockoo's answer is incorrect for both of the SQLs. Their first one would still allow %
through as Knex does not escape %
for LIKE
operations. The second SQL simply does not work as Knex wraps the bound value with quotes.
The correct way should be
const term = '10%'
const b = knex('table').where('description', 'like', `%${term.replaceAll('%', '\\%')}%`)
The output of b.toString()
is:
select * from "table" where "description" like E'%10\\%%'
Postgres will interpret E'\\%'
as '\%'
, which is an escaped percentage sign according to: https://www.postgresql.org/docs/current/functions-matching.html#FUNCTIONS-LIKE by default if you are on newer Postgres version.
This can be verified with this table:
CREATE TABLE test (
description character varying(256)
);
INSERT INTO test VALUES ('a%b');
and test the following:
%
like others have suggested. This shouldn't work.knex('test').where('description', 'like', 'a%%%b').toString()
select * from "test" where "description" like 'a%%%b'
description
-------------
a%b
(1 row)
Escaping %
before giving to Knex.
knex('test').where('description', 'like', 'a\\%\\%\\%b').toString()
select * from "test" where "description" like E'a\\%\\%\\%b'
description
-------------
(0 rows)
'a%b'
:knex('test').where('description', 'like', 'a\\%b').toString()
select * from "test" where "description" like E'a\\%b'
description
-------------
a%b
(1 row)
SQL Fiddle: http://sqlfiddle.com/#!17/d2f5e/1
Upvotes: 2
Reputation: 26
Hey have you tried this
knex('Quotes').where('quoteBody', 'like', **'%'+Quote+'%'**)
just the regular javascript escaping works just fine.
Upvotes: -1
Reputation: 14896
Knex doesn't have an equivalent to the ESCAPE
keyword [1], so you have to do a raw query like this, which will search for users with name === "%foo%"
:
knex.raw('select * from users where name like ? escape \', ['\%foo\%'])
And this, with an unescaped wildcard at the beginning of the search term, will search for users with name
ending in "%foo%"
:
knex.raw('select * from users where name like ? escape \', ['%\%foo\%'])
[1] Closed feature request: https://github.com/knex/knex/issues/648
Upvotes: 0
Reputation: 2392
For this case I use
rather string interpolation from es6
(safe version)
knex('table').where('description', 'like', `%${term}%`)
or ??
parameter binding
knex('table').whereRaw('description like \'%??%\'', [term])
But in the first case, you must be 100% sure that term is valid, because of the possibility of SQL injection.
Upvotes: 9
Reputation: 170
I have not used knex in a while so I can not test this. But have you tried to literally escape %? I hope that is what you want.
let term = "%something%"
let parsedTerm = term.replace("%", "\%")
console.log(parsedTerm);
Tell me about that please.
Upvotes: -3
Reputation:
Use the RLIKE instead of LIKE as below, It should work for you.
function search(term){
knex('table').where('description','rlike',term);
...
}
Upvotes: 0