2017-02-28 10 views
1

$like句で、(sqlite3を使用して)ワイルドカード文字(%_)をエスケープする方法を教えてください。

例えば、私は、任意の「things.description」に(だけでなく、単語の任意の文字に囲まれた「クール」)を文字列リテラル_cool_を見つけ、それ以下1に匹敵するクエリを生成したいのですが

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

一意のバックスラッシュをエスケープしている場合は、\\cool \ _としますか? – Xorifelse

+0

@Xorifelse JavaScriptでは、文字列リテラル ''\\ _''は文字列 '" \ _ "'と等しくなります。 – maerics

+1

これはちょうど後遺症であるかもしれません。https://github.com/sequelize/sequelize/issues/4317 – maerics

答えて

1

唯一のものは

LIKE '\_cool\_' ESCAPE '\' 
+0

良いアイデアは、SQLインジェクションを避けるために目標値自体をエスケープするだけで十分です。 – maerics

+0

Sequelizeは、注入を避けるために値をエスケープするために使用できる['escape'](http://docs.sequelizejs.com/en/latest/api/sequelize/#escapevalue-string)メソッドを提供しています – piotrbienias

0

任意のユーザ入力を受け取り、それを適切にエスケープし@piotrbieniasに基づいて完全なソリューションのようなSQLを生成

description: { 
    $like: sequelize.literal(`'\\_cool\\_' ESCAPE '\\'`) 
} 

ようなものです -

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 '\\' 

あなたのデフォルトのエスケープをSQLiteのMySQLを使用していないが、とにかく\のでESCAPE宣言を削除することができている場合は、あなたの実際の使用ケース

に応じて、他のワイルドカードを追加するためのロジックを変更することができます

関連する問題