Arduino写入RFID数据到MySQL时出现字符串字面量运算符报错
问题背景
开发基于Arduino框架的RFID刷卡识别项目时,尝试将变量存储的RFID卡号数据写入MySQL数据库时触发编译报错。
出错的SQL语句片段
String INSERT_SQL ="INSERT INTO database.table VALUES('0 ',"conteudo")";
编译抛出的错误信息
unable to find string literal operator 'operator""conteudo' with 'const char [43]', 'unsigned int' arguments
项目原始完整代码
#include <WiFi.h> #include <SPI.h> #include <MFRC522.h> #include <Servo.h> #include <MySQL_Generic.h> Servo servo; #define SS_PIN 21 #define RST_PIN 22 MFRC522 mfrc522(SS_PIN, RST_PIN); const char* ssid = ""; const char* password = ""; char user[] = ""; char passw[] = ""; String conteudo = ""; #define MYSQL_DEBUG_PORT Serial #define MYSQL_LOGLEVEL 0 #define USING_HOST_NAME true #if USING_HOST_NAME char server[] = ""; char default_database[] = ""; char default_table[] = ""; #else IPAddress server(192, 168, 0, 250); #endif uint16_t server_port = 3306; MySQL_Connection conn((Client *)&client); MySQL_Query *query_mem; int led_CH1 = 14; int pos = 0; void setup() { pinMode(led_CH1, OUTPUT); Serial.begin(115200); while (!Serial && millis() < 5000); SPI.begin(); iniciarWiFi(); MYSQL_DISPLAY1("Connecting to", ssid); MYSQL_DISPLAY3("Connecting to SQL Server @", server, ", Port =", server_port); MYSQL_DISPLAY5("User =", user, ", PW =", passw, ", DB =", default_database); mfrc522.PCD_Init(); servo.attach(25); servo.write(100); Serial.println("Aproxime o seu cartao do leitor..."); Serial.println(); } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } if ( ! mfrc522.PICC_ReadCardSerial()) { return; } Serial.print("UID da tag :"); byte letra; for (byte i = 0; i < mfrc522.uid.size; i++) { Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(mfrc522.uid.uidByte[i], HEX); conteudo.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ")); conteudo.concat(String(mfrc522.uid.uidByte[i], HEX)); } Serial.println(); Serial.print("Mensagem : "); conteudo.toUpperCase(); if (conteudo.substring(1) == "B0 21 A4 39") { digitalWrite(led_CH1, HIGH); Serial.println("Cartao1 - Acesso concedido!"); Serial.println(); String INSERT_SQL ="INSERT INTO database.table VALUES('0 ',"conteudo")"; if (conn.connectNonBlocking(server, server_port, user, passw) != RESULT_FAIL) { delay(500); runInsert(); conn.close(); } else { MYSQL_DISPLAY("\nConnect failed. Trying again on next iteration."); } delay(100); delay(3000); for (pos = 0; pos <= 180; pos += 1) { servo.write(pos); delay(15); } delay(1500); for (pos = 180; pos >= 0; pos -= 1) { servo.write(pos); delay(15); } digitalWrite(led_CH1, LOW); } if (conteudo.substring(1) != "B0 21 A4 39") { Serial.println("Cartao2 - Acesso negado !!"); Serial.println(); } delay(1000); } void iniciarWiFi() { WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print("A conectar ao WiFi ."); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(1000); } Serial.println(WiFi.localIP()); } void runInsert() { MySQL_Query query_mem = MySQL_Query(&conn); if (conn.connected()) { MYSQL_DISPLAY(INSERT_SQL); if ( !query_mem.execute(INSERT_SQL.c_str()) ) { MYSQL_DISPLAY("Insert error"); } else { MYSQL_DISPLAY("Data Inserted."); } } else { MYSQL_DISPLAY("Disconnected from Server. Can't insert."); } }
错误原因
- 核心编译报错由字符串拼接语法错误导致:直接把字符串字面量和变量
conteudo紧挨书写,既没有用Arduino String支持的+运算符做拼接,也没有给SQL中的字符串值补全单引号,C++编译器会将双引号后紧跟的标识符识别为自定义字符串字面量运算符,找不到对应实现就抛出该错误。 - 原代码还存在三处隐藏的编译/运行问题:
- 创建MySQL连接时用到的
client对象没有提前定义,缺少WiFiClient实例 INSERT_SQL定义在if判断的局部作用域内,全局的runInsert()函数无法访问该变量- 读卡前没有清空
conteudo变量,多次刷卡会导致卡号字符串叠加,校验逻辑失效
- 创建MySQL连接时用到的
修复方案
- 在全局变量区补充WiFiClient实例定义:
WiFiClient client; - 将
INSERT_SQL定义为全局String变量,避免作用域访问错误。 - 修正SQL语句赋值逻辑,用
+运算符拼接静态SQL片段和卡号变量,同时给卡号值包裹SQL要求的单引号,修正后语句为:INSERT_SQL = "INSERT INTO database.table VALUES('0 ', '" + conteudo.substring(1) + "')"; - 每次进入读卡逻辑前先执行
conteudo = "";清空历史数据,避免多次刷卡的卡号内容叠加。
修正后拼接出的SQL语句格式符合MySQL语法要求,不会再触发该编译错误。
内容的提问来源于stack exchange,提问作者João Ravasqueira
相关产品推荐
相关产品推荐

