You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL语句在Workbench正常运行,NodeJS调用时触发ER_PARSE_ERROR

问题:多语句SQL执行报错(ER_PARSE_ERROR)

我的代码

let sql = `INSERT INTO Users (Username, Password, FirstName, LastName, Permissions) VALUES ('${req.body.username}', '${hashedPassword}','${req.body.FirstName}','${req.body.LastName}', 'basic_client'); SELECT * FROM Users WHERE UserID = 1523595;`;

报错信息

code: 'ER_PARSE_ERROR', errno: 1064, sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT * FROM Users WHERE UserID = 1523595' at line 1"

已尝试的操作

  • 使用多行字符串,发现最后一行的SELECT语句引发问题,单独执行INSERT语句可正常运行;
  • 打印输出SQL语句并在Workbench中执行,可正常运行;
  • 单独执行查询UserID=1523595的语句在Workbench中也正常;
  • 将SQL替换为仅SELECT 1523595时,服务器可正常执行,但其他语句均不行。

解决方法

问题核心是Node.js的MySQL驱动默认禁止执行多语句查询,这是安全默认配置(防止SQL注入),所以直接拼接INSERT+SELECT的多语句会触发语法错误。

方案1:拆分语句分两次执行(推荐)

把INSERT和SELECT拆成两个独立查询,先执行插入再执行查询:

// 回调写法
connection.query(`INSERT INTO Users (Username, Password, FirstName, LastName, Permissions) VALUES ('${req.body.username}', '${hashedPassword}','${req.body.FirstName}','${req.body.LastName}', 'basic_client')`, (err, insertRes) => {
  if (err) throw err;
  connection.query(`SELECT * FROM Users WHERE UserID = 1523595`, (err, selectRes) => {
    if (err) throw err;
    console.log(selectRes);
    // 处理返回结果
  });
});

// Async/Await写法(更清晰)
async function createAndGetUser() {
  try {
    await connection.query(`INSERT INTO Users (Username, Password, FirstName, LastName, Permissions) VALUES ('${req.body.username}', '${hashedPassword}','${req.body.FirstName}','${req.body.LastName}', 'basic_client')`);
    const user = await connection.query(`SELECT * FROM Users WHERE UserID = 1523595`);
    console.log(user);
  } catch (err) {
    console.error(err);
  }
}

方案2:开启多语句支持(不推荐)

如果必须用多语句,需在创建数据库连接时开启multipleStatements配置,但会大幅提升SQL注入风险,仅建议测试环境临时使用:

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'your_user',
  password: 'your_password',
  database: 'your_db',
  multipleStatements: true // 开启多语句支持
});

方案3:使用INSERT...RETURNING(MySQL 8.0.19+支持)

如果你的MySQL版本符合要求,可直接用RETURNING子句在插入后返回数据,无需单独执行SELECT:

let sql = `INSERT INTO Users (Username, Password, FirstName, LastName, Permissions) VALUES ('${req.body.username}', '${hashedPassword}','${req.body.FirstName}','${req.body.LastName}', 'basic_client') RETURNING *;`;

SQL注入防护建议

针对你提到的后续要处理SQL注入,给出核心建议:

  • 强制使用参数化查询:永远不要直接拼接用户输入到SQL语句,用驱动提供的参数占位符:
    const sql = `INSERT INTO Users (Username, Password, FirstName, LastName, Permissions) VALUES (?, ?, ?, ?, ?)`;
    connection.query(sql, [req.body.username, hashedPassword, req.body.FirstName, req.body.LastName, 'basic_client'], (err, results) => {
      // 处理结果
    });
    
  • 禁止开启多语句支持:除非极端场景,否则不要打开multipleStatements,这是SQL注入高危点;
  • 校验用户输入:提前过滤非法字符、限制输入长度,比如用户名只允许字母数字下划线;
  • 使用ORM框架:如Sequelize、TypeORM,框架会自动处理参数化查询,大幅降低注入风险。

内容的提问来源于stack exchange,提问作者Mel Habip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 00:30:54