谁能告诉我为什么会发生MySQL语法错误?

时间:2018-09-07 02:35:00

标签: javascript mysql node.js

app.get('/delete_server',function(req,res){
    var before_page = req.query.before;
    var title = req.query.title;
    var sql = 'delete from ? where title=?';

    conn.query(sql,[before_page,title],function(err,rows,fields){
        if(err) console.log(err);
        else {
            console.log(rows[0]);
            res.redirect('/menu/'+before_page);
        }
    })
})

我正在尝试使用querystring和sql查询来删除服务器。 但这是行不通的。控制台说这是SQL语法错误。 我认为问题是before_page变量。 SQL查询成为delete from 'japan' where title='test' 我认为“日本”是错误的。

我该怎么办?

2 个答案:

答案 0 :(得分:1)

在后台,JavaScript库使用MySQL prepared statements运行查询。 PREPARE MySQL语句的文档说明:

  

参数标记只能用于应该显示数据值的位置,而不能用于SQL关键字,标识符等。

这意味着您不能将?用作命令名(SELECTDELETE等),MySQL关键字(FROMAND等的占位符或函数(MIN()SUBSTR()等),数据库名称,表名称或字段名称。这样只能替换值。

您的代码的解决方案是:

var sql = 'delete from `'+before_page+'` where title=?';

conn.query(sql, [title], function(err, rows, fields) {
   // ...
}

或者,对于ES5和更高版本,您可以使用template literals

var sql = `delete from \`${before_page}\` where title=?`;

您必须确保before_page的值是有效的表名。如果您从请求中得到它,则您的代码可以进行SQL注入。

对照表名的白名单检查输入值,或者更好的是,不要将表名泄漏到应用程序之外;为您处理的实体使用通用名称,并在公共名称和表名称之间保持映射。

通过在此映射中查找req.query.before的值来查找表名称。如果输入值不在地图中,则拒绝该操作。

答案 1 :(得分:0)

我将变量“ sql”更改为:

'delete from '+before_page+' where title=?'
相关问题