如何告诉sequelize(使用sqlite3)在%
子句中转义通配符(_
,$like
)?
例如,我想生成一个与下面的查询相似的查询,该查询在任何" things.description"中找到文字字符串_cool_
。 (不只是单词" cool"被任何字符包围):
SELECT * FROM things WHERE description LIKE '\_cool\_' ESCAPE '\';
我猜它看起来像这样,但结果查询不是我希望的:
Thing.findAll({
where: {
description: {
$like: ['?', '_cool_'],
// ... or ...
$like: '\\_cool\\_',
$escape: '\\',
}
}
});
// => Executing (default):
// SELECT `id`, `description`
// FROM `Things` AS `Thing`
// WHERE `Thing`.`description` LIKE '?','_cool_';
不幸的是,我不能放入原始查询,因为" LIKE"子句将成为更大的动态查询的一部分。
有什么想法吗?
答案 0 :(得分:1)
我唯一想到的就是
description: {
$like: sequelize.literal(`'\\_cool\\_' ESCAPE '\\'`)
}
生成类似
的SQLLIKE '\_cool\_' ESCAPE '\'
答案 1 :(得分:0)
基于@piotrbienias的完整解决方案,可以接受任何用户输入并正确地逃避它 -
if (typeof query.string !== 'string') {
throw Error('expecting string')
}
const inputRaw = query.string.replace(/(_|%|\\)/g, '\\$1');
const inputSec = sequelize.escape(`%${inputRaw}%`);
description = {
$like: sequelize.literal(`${inputSec} ESCAPE '\\'`)
};
对于示例字符串_cool_
,这将转换为 -
LIKE '%\\_cool\\_%' ESCAPE '\\'
您可以根据实际用例更改逻辑以添加其他通配符
如果你使用mysql而不是sqlite,那么默认的转义是\
所以可以删除ESCAPE声明