How do I escape % in Knex where like query?

后端 未结 6 1440
挽巷
挽巷 2021-01-18 00:09

I\'m using knex to generate my SQL queries. In knex documentation, it shows this

knex(\'users\').where(\'columnName\', \'like\', \'         


        
相关标签:
6条回答
  • 2021-01-18 00:50

    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

    0 讨论(0)
  • 2021-01-18 00:53

    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.

    0 讨论(0)
  • 2021-01-18 01:03

    Hey have you tried this

    knex('Quotes').where('quoteBody', 'like', **'%'+Quote+'%'**)
    
    

    just the regular javascript escaping works just fine.

    0 讨论(0)
  • 2021-01-18 01:04

    @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:

    1. Without escaping % 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)
    
    1. Escaping % before giving to Knex.

      1. This should return no rows:
      knex('test').where('description', 'like', 'a\\%\\%\\%b').toString()
      
      select * from "test" where "description" like E'a\\%\\%\\%b'
      
       description
      -------------
      (0 rows)
      
      1. This should return '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

    0 讨论(0)
  • 2021-01-18 01:05

    Use the RLIKE instead of LIKE as below, It should work for you.

    function search(term){
        knex('table').where('description','rlike',term);
        ...
    }
    
    0 讨论(0)
  • 2021-01-18 01:09

    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.

    0 讨论(0)
提交回复
热议问题