javascript 将变量插入sqlite查询

ltqd579y  于 2023-01-04  发布在  Java
关注(0)|答案(2)|浏览(129)

如果表1中的列“description”包含某个子字符串,我将尝试从3个不同的表中获取行。
这段代码工作正常,并给我带来了理想的结果:

sql = "SELECT * FROM NonMandatoryObject 
 JOIN Object ON Object.M_id = NonMandatoryObject.NM_id 
JOIN Pictures ON Pictures.PICS_id = NonMandatoryObject.NM_id 
WHERE  description like '%TheSubStringIWantToSearch%'   "

db.all(sql,   (err, rows) => {
        if (err) console.log('failure')
        else {
            res.send(rows)
            console.log('success')
        }
    })

问题是程序的格式是在不同的数组中包含变量,当我用“?”代替变量名并提供这个名称时,搜索崩溃了。

sql = "SELECT * FROM NonMandatoryObject 
 JOIN Object ON Object.M_id = NonMandatoryObject.NM_id 
JOIN Pictures ON Pictures.PICS_id = NonMandatoryObject.NM_id 
WHERE  description like '%?%'   "

arr = ['TheSubStringIWantToSearch']

db.all(sql, arr, (err, rows) => {
        if (err) console.log('failure')
        else {
            res.send(rows)
            console.log('success')
        }
    })

将变量名插入SQL查询的正确方法是什么?
谢谢。

qzwqbdag

qzwqbdag1#

我想你可能会觉得这个答案很有趣(它在python中,但有类似的想法):https://stackoverflow.com/a/3105370/7045733
我的理解是,要将?视为占位符,它需要独立(而不是在引号内),因此在将字符串传递给SQLite之前,需要将“%”符号添加到字符串中。(例如,您需要传递“% TheSubStringIWantToSearch %”,而不是从代码中传递“TheSubStringIWantToSearch %”)。
请注意,如果'TheSubStringIWantToSearch'可以包含LIKE比较使用的任何特殊符号(看起来'%'和'_'是SQLite中LIKE表达式中使用的唯一特殊符号:https://www.sqlite.org/lang_expr.html#like),那么你需要使用escaping.See this paragraph from the documentation来获得更多细节。如果你想搜索的子字符串来自用户,我强烈建议实现escaping,因为你永远不知道他们要搜索什么!
对于转义,您可以实现如下代码:

sql = "SELECT * FROM NonMandatoryObject 
 JOIN Object ON Object.M_id = NonMandatoryObject.NM_id 
JOIN Pictures ON Pictures.PICS_id = NonMandatoryObject.NM_id 
WHERE  description like ? escape '!'"

arr = ['%' + searchSubstring.replace(/_/g, '!_').replace(/%/g, '!%') + '%']

db.all(sql, arr, (err, rows) => {
        if (err) console.log('failure')
        else {
            res.send(rows)
            console.log('success')
        }
    })

关于Peter Thoeny的回答:

我建议避免使用.replace()将数据格式化为sql数据字符串本身,因为这可能会导致SQL注入,这可能是危险的(特别是在用户生成的内容上)。

icnyk63a

icnyk63a2#

您可以创建一个包含%LIKE%之类的标记(或多个标记,如果需要)的SQL模板。然后,您可以使用.replace()将标记替换为搜索字符串来基于该模板创建SQL:

const sqlTemplate = `SELECT * FROM NonMandatoryObject 
 JOIN Object ON Object.M_id = NonMandatoryObject.NM_id 
JOIN Pictures ON Pictures.PICS_id = NonMandatoryObject.NM_id 
WHERE  description like '%LIKE%'   `

const arr = ['TheSubStringIWantToSearch'];

let likeValue = '%'
  + arr[0]
    .replace(/['"\x00-\x1f]/g, '') // remove dangerous chars
    .replace(/([%_])/g, '!$1')     // escape % and _
  + '%';
let sql = sqlTemplate.replace(/%LIKE%/, likeValue);
db.all(sql,   (err, rows) => {
        if (err) console.log('failure')
        else {
            res.send(rows)
            console.log('success')
        }
    })

注意,likeValue删除了特殊的SQL字符(以防止SQL注入攻击),并转义了%_

相关问题