使用C语言向MariaDB插入datetime数据时遇语法错误求助
C语言向MariaDB插入datetime数据的语法错误解决方法
问题根源
你生成的SQL语句中,字符串类型的sn和datetime类型的date都没有用单引号包裹,导致MariaDB解析时出现语法错误:
fb8e2ffb会被当成标识符而非字符串2022-09-18会被解析成数值运算(2022减9减18),后续的19:04:28就成了非法语法,这就是报错的直接原因。
快速修复代码
修改sprintf的格式字符串,给字符串类型参数加上单引号:
t = time(NULL); struct tm tm = *localtime(&t); sprintf(curTime, "%d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); // 给%s添加单引号包裹 sprintf(sql, "INSERT INTO dataTable (sn, date, value_1, value_2) VALUES ('%s','%s',%.1f,%.1f)", rxsn, curTime, temp, hud);
修改后生成的SQL会变成合法格式:
INSERT INTO dataTable (sn, date, value_1, value_2) VALUES ('fb8e2ffb', '2022-09-18 19:04:28',21.6,61.1)
更安全的方案:参数化查询
用sprintf拼接SQL存在SQL注入风险,推荐使用MariaDB的参数化查询接口(预处理语句),示例代码如下:
MYSQL_STMT *stmt; MYSQL_BIND bind[4]; memset(bind, 0, sizeof(bind)); // 准备带占位符的SQL语句 const char *sql = "INSERT INTO dataTable (sn, date, value_1, value_2) VALUES (?, ?, ?, ?)"; stmt = mysql_stmt_init(conn); if (!mysql_stmt_prepare(stmt, sql, strlen(sql))) { // 绑定sn参数(字符串类型) bind[0].buffer_type = MYSQL_TYPE_STRING; bind[0].buffer = rxsn; bind[0].buffer_length = strlen(rxsn); // 绑定date参数(字符串类型) bind[1].buffer_type = MYSQL_TYPE_STRING; bind[1].buffer = curTime; bind[1].buffer_length = strlen(curTime); // 绑定value_1参数(浮点类型) bind[2].buffer_type = MYSQL_TYPE_FLOAT; bind[2].buffer = &temp; // 绑定value_2参数(浮点类型) bind[3].buffer_type = MYSQL_TYPE_FLOAT; bind[3].buffer = &hud; if (mysql_stmt_bind_param(stmt, bind)) { fprintf(stderr, "绑定参数失败: %s\n", mysql_error(conn)); } else { mysql_stmt_execute(stmt); } } mysql_stmt_close(stmt);
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

