如何通过MySQL C API加载SQL Dump文件至数据库?
解决MySQL C API无法执行
SOURCE命令加载.sql文件的问题 嘿,我懂你碰到的坑了——SOURCE其实是MySQL命令行客户端专属的命令,并不是MySQL服务器能直接解析的SQL语句,所以你用C API直接把它当SQL执行肯定会报语法错误。别慌,咱们可以换个思路:自己读取.sql文件的内容,再通过C API把这些SQL语句发送给服务器执行。
下面是具体的实现步骤和代码示例:
核心思路
- 读取目标.sql文件的全部内容到内存缓冲区
- 开启MySQL C API的多语句支持(如果你的.sql文件里包含多个用分号分隔的SQL语句)
- 把读取到的SQL内容发送给服务器执行
- 处理多语句执行后的结果集(避免残留资源)
完整代码示例
#include <stdio.h> #include <stdlib.h> #include <mysql/mysql.h> // 读取SQL文件内容到缓冲区的工具函数 char* read_sql_file(const char* filename, size_t* file_size) { FILE* file = fopen(filename, "r"); if (!file) { perror("Failed to open SQL file"); return NULL; } // 获取文件总大小 fseek(file, 0, SEEK_END); *file_size = ftell(file); fseek(file, 0, SEEK_SET); // 分配缓冲区,额外留一个字节存字符串结束符 char* buffer = malloc(*file_size + 1); if (!buffer) { perror("Failed to allocate memory"); fclose(file); return NULL; } // 读取文件内容到缓冲区 size_t bytes_read = fread(buffer, 1, *file_size, file); if (bytes_read != *file_size) { perror("Failed to read SQL file completely"); free(buffer); fclose(file); return NULL; } buffer[*file_size] = '\0'; // 确保是合法的C字符串 fclose(file); return buffer; } int main() { MYSQL* conn = mysql_init(NULL); if (!conn) { fprintf(stderr, "mysql_init failed: insufficient memory\n"); return 1; } // 替换成你的数据库连接信息 if (!mysql_real_connect(conn, "localhost", "your_username", "your_password", "your_database", 0, NULL, 0)) { fprintf(stderr, "Connection failed: %s\n", mysql_error(conn)); mysql_close(conn); return 1; } // 开启多语句支持(如果SQL文件里有多个分号分隔的语句,必须开启这个) if (mysql_set_server_option(conn, MYSQL_OPTION_MULTI_STATEMENTS_ON) != 0) { fprintf(stderr, "Failed to enable multi-statements: %s\n", mysql_error(conn)); mysql_close(conn); return 1; } size_t file_size; // 替换成你的.sql文件路径 char* sql_content = read_sql_file("/home/iota/Academics/4-2/NP/a/a4/cars.sql", &file_size); if (!sql_content) { mysql_close(conn); return 1; } // 执行读取到的SQL内容 if (mysql_real_query(conn, sql_content, file_size) != 0) { fprintf(stderr, "SQL execution failed: %s\n", mysql_error(conn)); free(sql_content); mysql_close(conn); return 1; } // 处理多语句执行后的所有结果集,避免内存泄漏 do { MYSQL_RES* result = mysql_store_result(conn); if (result) { mysql_free_result(result); } } while (mysql_next_result(conn) == 0); printf("SQL file loaded and executed successfully!\n"); // 清理资源 free(sql_content); mysql_close(conn); return 0; }
注意事项
- 编译链接:编译时要链接MySQL客户端库,比如用命令:
gcc your_code.c -o sql_loader -lmysqlclient - 大文件处理:如果你的.sql文件特别大,直接一次性读取到内存可能会有问题,这时候可以考虑分块读取并拆分SQL语句执行,但一般中小型文件用上面的方法足够
- 安全问题:如果.sql文件来自不可信来源,开启多语句支持可能会有SQL注入风险,务必确保文件的安全性
- 语法检查:提前确保.sql文件里的SQL语句没有语法错误,否则执行时会报错
内容的提问来源于stack exchange,提问作者Siddharth
相关产品推荐
相关产品推荐

