使用 NodeJS 在 mySQL 中插入多条记录以防止注入并获取每条记录的 ID
Posted
技术标签:
【中文标题】使用 NodeJS 在 mySQL 中插入多条记录以防止注入并获取每条记录的 ID【英文标题】:Inserting multiple records in mySQL with NodeJS preventing injection and getting each record's ID 【发布时间】:2019-10-15 00:06:05 【问题描述】:我有一个将一条或多条记录添加到表中的 ajax 请求(以下代码是服务器端的):
app.post('/saveLesson',function(req, res)
let sections = JSON.parse(req.body.sections);
let sql = 'INSERT INTO sections (title, content, duration) VALUES ';
for (let i = 0; i < sections.length; i++)
if (i == sections.length-1)
sql += '("' + sections[i].title + '","' + sections[i].content + '","' + sections[i].duration + '");';
else
sql += '("' + sections[i].title + '","' + sections[i].content + '","' + sections[i].duration + '"),';
connection.query(sql,
function (error, result)
if (error) throw error;
);
);
我想防止 SQL 注入,但我不确定如何针对多条记录执行此操作。
通常我知道我必须按如下方式构建我的 sql 语句:
connection.query("SELECT * FROM bank_accounts WHERE dob = ? AND bank_account = ?",
[
req.body.dob,
req.body.account_number
],
function(error, results)
);
但我不确定如何使用多条记录来实现这一点(不知道它们有多少)。 .query 参数只是一个常规数组吗?
另外,我需要将创建的 ID 存储在某处并将它们发送回客户端页面。我怎样才能做到这一点?谢谢。
********************************** 更新 ***************** ************
虽然有人发布了解决方案,但我认为这可能有用。使用以下代码,您可以添加多条记录以防止 SQL 注入。
app.post('/saveLesson',function(req, res)
let sections = JSON.parse(req.body.sections);
console.log(sections);
let sql = 'INSERT INTO sections (title, duration, content) VALUES ';
// I make a new array to pass the list of values to the query
let sectionsParamList = [];
for (let i = 0; i < sections.length; i++)
if (i == sections.length-1)
sql += '(?,?,?);';
else
sql += '(?,?,?),';
sectionsParamList.push(sections[i].title);
sectionsParamList.push(sections[i].duration);
sectionsParamList.push(sections[i].content);
connection.query(sql, sectionsParamList,
function (error, result)
if (error) throw error;
);
);
【问题讨论】:
Also I need to store somewhere the created IDs and send them back to the client page.
您可以自己生成主键,而不是使用自动增量主键,即microshell.com/database/mysql/…
有趣的链接,谢谢。在客户端,我还有要插入的记录的 ID(增量数字 + Math.random() - 这些仅在客户端页面中是唯一的,而不是在数据库中)。是否建议将具有此 ID 的记录与其他信息一起添加,然后使用“虚拟”ID 检索由数据库创建的唯一 ID?我想我最终会得到一个无用的字段,除非我为其他数据回收它。
【参考方案1】:
MySQL 的工作方式是,当您像您建议的那样执行多行INSERT
操作时,您只能取回插入的最后一行的自动生成的唯一id
。它在您的result
对象中显示为result.insertId
。不要试图猜测其他行的 id
值,例如通过减法,因为不能保证。
您插入的每一行都需要id
,这意味着您不应使用多行插入,而应使用单行插入序列。这也巧妙地解决了您的 SQL 注入问题。
但是您必须弄清楚如何进行一系列INSERT
操作。您可能希望使用 async / await / promise 设置来做到这一点。像这样的东西,未调试。
/* do one insert with a Promise so you can await it */
function doInsert (section, connection)
const values = [section.title, section.content, section.duration];
return new Promise( function ( resolve, reject )
const sql = "INSERT INTO sections (title, content, duration) VALUES (?,?,?);"
connection.query (sql, values, function ( error, result )
if (error) reject (error)
resolve (result.insertId)
)
)
/* do all the inserts, awaiting each one */
async function doInserts (sections, connection)
let ids = []
for (let i = 0; i < sections.length; i++)
const id = await doInsert (sections[i], connection)
ids.push(id)
return ids
/* handle your post */
app.post('/saveLesson',function(req, res)
let sections = JSON.parse(req.body.sections)
/* get the result back from an async function with .then / .catch */
doInserts (sections, connection)
.then (function (resultIds)
/* respond with the id values in a JSON object */
res.status(200).json(resultIds)
)
.catch ( function (error)
/* respond with an error */
res.status(500).json(error)
)
)
如果您还不了解这些 async / await 和 Promise 语言结构,那么您真的值得您学习它们。
【讨论】:
我承认我对 async / await 和 Promise 了解不多。我绝对需要学习如何使用它们。谢谢你的帖子。以上是关于使用 NodeJS 在 mySQL 中插入多条记录以防止注入并获取每条记录的 ID的主要内容,如果未能解决你的问题,请参考以下文章
在一个查询中使用 MySqlCommand 将多条记录插入 MySQL C# (MySQLConnector) & command 转义引号的参数
如果 mysql 数据库中的表中不存在,则更新或插入多条记录