如何在Knex中像%查询一样转义%?

时间:2018-05-14 09:28:15

标签: javascript mysql node.js knex.js

我正在使用knex来生成我的SQL查询。在knex文档中,它显示了此

knex('users').where('columnName', 'like', '%rowlikeme%')

现在在我的申请中,我这样做了:

function search(term) {
  term = "%" + term + "%";
  knex('table').where('description', 'like', term);
  // ...
}

我如何逃避%,以便它也会在%作为该术语的一部分进行搜索?

感谢。

7 个答案:

答案 0 :(得分:1)

使用RLIKE代替LIKE,如下所示,它应该适合你。

function search(term){
    knex('table').where('description','rlike',term);
    ...
}

答案 1 :(得分:1)

我有一段时间没用过knex,所以我无法测试。但你有没有试图逃脱%?我希望这就是你想要的。

let term = "%something%"
let parsedTerm = term.replace("%", "\%")
console.log(parsedTerm);

请告诉我。

答案 2 :(得分:1)

对于这种情况,我使用

来自es6(安全版)的字符串插值

knex('table').where('description', 'like', `%${term}%`)

??参数binding

knex('table').whereRaw('description like \'%??%\'', [term])

但是在第二种情况下,你必须100%确定该术语是有效的,因为SQL注入的可能性(我不确定,也许评论中有人会指出这一点,但我宁愿不冒险)

答案 3 :(得分:0)

Knex没有与ESCAPE关键字[1]等效的关键字,因此您必须执行类似的原始查询,该查询将使用name === "%foo%"搜索用户:

knex.raw('select * from users where name like ? escape \', ['\%foo\%'])

这将在搜索词的开头加上一个未转义的通配符,将搜索以name结尾的"%foo%"的用户:

knex.raw('select * from users where name like ? escape \', ['%\%foo\%'])

[1]封闭功能请求:https://github.com/knex/knex/issues/648

答案 4 :(得分:0)

对于两个SQL,

@coockoo的答案均不正确。他们的第一个仍将允许%通过,因为Knex不能为%的操作转义LIKE。第二个SQL根本不起作用,因为Knex 用引号引起来的绑定值

正确的方法应该是

const term = '10%'
const b = knex('table').where('description', 'like', `%${term.replaceAll('%', '\\%')}%`)

b.toString()的输出是:

select * from "table" where "description" like E'%10\\%%'

Postgres会将E'\\%'解释为'\%',根据以下情况,这是一个转义的百分号:https://www.postgresql.org/docs/current/functions-matching.html#FUNCTIONS-LIKE(如果您使用的是较新的Postgres版本)。


可以通过此表进行验证:

CREATE TABLE test (
    description character varying(256)
);

INSERT INTO test VALUES ('a%b');

并测试以下内容:

  1. 请勿像其他人建议的那样转义%。此操作不起作用
knex('test').where('description', 'like', 'a%%%b').toString()
select * from "test" where "description" like 'a%%%b'
 description
-------------
 a%b
(1 row)
  1. 在送给Knex之前先转义%

    1. 这应该不返回任何行:
    knex('test').where('description', 'like', 'a\\%\\%\\%b').toString()
    
    select * from "test" where "description" like E'a\\%\\%\\%b'
    
     description
    -------------
    (0 rows)
    
    1. 这应该返回'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小提琴:http://sqlfiddle.com/#!17/d2f5e/1

答案 5 :(得分:0)

所以我一直在寻找将 LOWER 函数应用于参数的正确方法。这是对我来说似乎工作正常的解决方案:

builder.whereRaw('LOWER(last_name) LIKE LOWER(?)', [`%${lastName}%`])

答案 6 :(得分:-1)

嘿,你试过了

Unable to load class "org.jaffa.datatypes.configurer.MybatisConfigurer" due to exception: java.lang.ClassNotFoundException: org.jaffa.datatypes.configurer.MybatisConfigurer

只是常规的javascript转义就可以了。