Node-RED MySQL节点SQL语法错误排查:Arduino数据无法入库
Node-RED MySQL插入语句语法错误解决办法
问题现象
数据从Arduino经串口传至Node-RED并解析为JSON后,通过Function节点生成SQL插入语句,手动在phpMyAdmin执行该SQL正常,但Node-RED中使用node-red-node-mysql节点执行时报错:
Error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
相关代码片段
- Function节点原代码:
// Set the table name and fields var tableName = "sensordata"; var fields = ["rpm", "water", "temp", "humidity"]; // Create the SQL query string var values = []; fields.forEach(function(field) { values.push(msg.payload[field]); }); var sqlQuery = "INSERT INTO " + tableName + " (" + fields.join(",") + ") VALUES (" + values.join(",") +")"; // Store the SQL query in the message payload msg.topic = "INSERT INTO sensordata"; msg.payload = sqlQuery; return msg;
- Arduino序列化JSON代码:
StaticJsonDocument<200> jsonDoc; jsonDoc["rpm"] = rpm; jsonDoc["water"] = Water; jsonDoc["temp"] = temp; jsonDoc["humidity"] = hum; // Serialize the JsonObject to a string char jsonString[200]; serializeJson(jsonDoc, jsonString); // Print the JSON string to the serial monitor Serial.println(jsonString);
- 传入Node-RED的JSON:
{"rpm":223.2857,"water":0,"temp":27.9,"humidity":46}
- 生成的SQL语句:
INSERT INTO sensordata (rpm, water, temp, humidity) VALUES (223.2857, 0, 27.9, 46)
错误原因
node-red-node-mysql节点的消息格式要求被错误使用:
- 节点预期
msg.topic存储SQL模板(或完整SQL语句),msg.payload存储参数数组(或为空) - 原代码将完整SQL放在
msg.payload,同时msg.topic只写了半截语句,导致节点解析时出现语法混乱
解决方案
方案1:参数化查询(推荐,防SQL注入)
按照MySQL节点的标准格式构造消息,用?作为占位符,由节点自动处理参数拼接:
// 定义表名和字段 const tableName = "sensordata"; const fields = ["rpm", "water", "temp", "humidity"]; // 提取对应字段的值 const values = fields.map(field => msg.payload[field]); // 构造带占位符的SQL模板 const sqlTemplate = `INSERT INTO ${tableName} (${fields.join(",")}) VALUES (${fields.map(() => "?").join(",")})`; // 设置消息格式 msg.topic = sqlTemplate; msg.payload = values; return msg;
方案2:直接传递完整SQL(不推荐,存在注入风险)
若坚持使用拼接好的完整SQL,需将完整语句放入msg.topic,并清空msg.payload:
const tableName = "sensordata"; const fields = ["rpm", "water", "temp", "humidity"]; const values = fields.map(field => msg.payload[field]); const fullSql = `INSERT INTO ${tableName} (${fields.join(",")}) VALUES (${values.join(",")})`; // 关键:完整SQL存入msg.topic,payload设为null msg.topic = fullSql; msg.payload = null; return msg;
验证步骤
- 部署修改后的Function节点
- 触发数据传输流程,通过Node-RED调试面板查看
msg.topic和msg.payload的格式是否符合要求 - 检查数据库,确认数据成功插入
内容的提问来源于stack exchange,提问作者user19683237
相关产品推荐
相关产品推荐

