You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过MySQL C API加载SQL Dump文件至数据库?

解决MySQL C API无法执行SOURCE命令加载.sql文件的问题

嘿,我懂你碰到的坑了——SOURCE其实是MySQL命令行客户端专属的命令,并不是MySQL服务器能直接解析的SQL语句,所以你用C API直接把它当SQL执行肯定会报语法错误。别慌,咱们可以换个思路:自己读取.sql文件的内容,再通过C API把这些SQL语句发送给服务器执行。

下面是具体的实现步骤和代码示例:

核心思路

  1. 读取目标.sql文件的全部内容到内存缓冲区
  2. 开启MySQL C API的多语句支持(如果你的.sql文件里包含多个用分号分隔的SQL语句)
  3. 把读取到的SQL内容发送给服务器执行
  4. 处理多语句执行后的结果集(避免残留资源)

完整代码示例

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:49:03