MySQL CAPI调用mysql_query执行多语句SQL报错1064求助
问题解决方法
核心原因
MySQL CAPI的mysql_query函数默认不允许在单个调用中执行多条用分号分隔的SQL语句,这和MySQL命令行客户端的默认行为不同,所以你把LOCK、SET、CALL、UNLOCK放在一个字符串里执行会触发语法错误。
解决步骤
1. 开启多语句支持
在建立MySQL连接时,需要在mysql_real_connect的client_flags参数中添加CLIENT_MULTI_STATEMENTS标志,示例代码:
MYSQL* conn = mysql_init(nullptr); // 将CLIENT_MULTI_STATEMENTS加入客户端标志位 unsigned long client_flags = CLIENT_MULTI_STATEMENTS | CLIENT_DEFAULT; if (!mysql_real_connect(conn, "你的主机地址", "用户名", "密码", "数据库名", 3306, nullptr, client_flags)) { // 处理连接错误逻辑 fprintf(stderr, "连接失败: %s\n", mysql_error(conn)); return; }
2. 正确处理多语句执行后的结果
执行多语句后,必须循环处理每个语句的返回结果,否则会导致后续SQL执行异常:
const char* sql = "LOCK TABLE `t_role` WRITE, `t_role` AS `t1` READ;SET @ret = 0;CALL create_role(12, @ret);UNLOCK TABLES;"; auto ret = mysql_query(conn, sql); if (ret != 0) { fprintf(stderr, "执行错误: %s\n", mysql_error(conn)); return; } // 循环遍历所有语句的结果集,释放资源 do { MYSQL_RES* res = mysql_store_result(conn); if (res != nullptr) { mysql_free_result(res); } } while (mysql_next_result(conn) == 0);
3. 修正变量名不一致问题
你的代码中SET @val_ret = 0和CALL create_role(12, @ret)的变量名不统一,会导致存储过程无法获取你设置的0值,需要将变量名改为一致(比如统一用@ret)。
额外注意事项
- 开启
CLIENT_MULTI_STATEMENTS后,若SQL语句包含用户输入,必须严格做转义处理,避免SQL注入风险。 - 执行
LOCK TABLE后,当前连接只能访问被锁定的表,直到执行UNLOCK TABLES,需确保存储过程create_role中仅操作t_role或已被锁定的表,否则会触发报错。
内容的提问来源于stack exchange,提问作者Xiang
相关产品推荐
相关产品推荐

