如何在C中使用mysql_connector执行sql文件

问题描述 投票:0回答:1

我只想使用C语言在mysql服务器中执行SQL文件。

我尝试了像这样的命令“source”:

mysql_query(conn, "source path/to/your/file.sql")

但我发现 mysql_connector 无法获取源代码。

然后我尝试读取buf中的文件并将其交给

mysql_query()

这是我的 C 代码:

#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>

size_t get_file_size(char *path);

int main() {

    /* Declaration */

    MYSQL *conn;
    char username[] = "user";
    char passwd[] = "user";
    char host[] = "localhost";
    char database[] = "";
    char sql_file_path[] = "./db.sql";
    char *sql_file;
    size_t sql_file_sz;
    FILE *sql_fs;

    /* Initialisation */

    sql_file_sz = get_file_size(sql_file_path);
    sql_file = (char *)calloc(sql_file_sz, sizeof(char));
    sql_fs = fopen(sql_file_path, "r");
    if (!sql_fs)
    {
        perror("Error : ");
        goto FatalError;
    }
    fread(sql_file, sql_file_sz, 1, sql_fs);
    if (ferror(sql_fs))
    {
        perror("Error : ");
        goto FatalError;
    }

    conn = mysql_init(NULL);
    
    if (conn == NULL) {
        fprintf(stderr, "Error : mysql_init() failed\n");
        goto FatalError;
    }
    
    // Connecting to mysql server
    if (!mysql_real_connect(conn, host, username, passwd, database, 0, NULL, 0)) {
        fprintf(stderr, "Error : mysql_real_connect() failed\n");
        goto FatalError;
    }
    printf("Connected.\n");

    if (mysql_query(conn, sql_file) != 0)
    {
        fprintf(stderr, "Error : mysql_query() failed : %s\n", mysql_error(conn));
        goto FatalError;
    }

    /* Leaving */

    mysql_close(conn);
    fclose(sql_fs);
    free(sql_file);
    
    printf("Exit success.\n");
    return EXIT_SUCCESS;

FatalError:

    if (conn)
        mysql_close(conn);
    if (sql_fs)
        fclose(sql_fs);
    if (sql_file)
        free(sql_file);

    printf("Exit with failure.\n");
    return EXIT_FAILURE;
}

/* 
    Return file size.

    On error, return -1;
*/
size_t get_file_size(char *path)
{
    size_t sz;
    FILE *fp;
    
    fp = fopen(path, "r");
    if (!fp)
    {
        perror("Error : ");
        fclose(fp);
        return -1;
    }

    fseek(fp, 0L, SEEK_END);
    sz = ftell(fp);
    rewind(fp);

    fclose(fp);

    return sz;
}

还有“db.sql”文件:

DROP DATABASE IF EXISTS vacance;

CREATE DATABASE vacance;

USE vacance;

CREATE TABLE Village (
    CodeVillage int,
    NomVillage varchar(30),
    Situation varchar(30)
);

当我使用 mysql-server shell 执行 sql 文件时,它可以工作。 但是使用 C 代码时我遇到了这个错误:

Connected.
Error : mysql_query() failed : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE DATABASE vacance;

USE vacance;

CREATE TABLE Village (
    CodeVillage i' at line 3
Exit with failure

有人可以指导我吗?

sql mysql c linux mysql-connector
1个回答
0
投票

source
命令仅被mysql客户端识别。有许多由客户端解析的“内置命令”。这意味着 MySQL 服务器的 SQL 解析器无法识别它们。它们只能被 mysql 客户端工具识别。

mysql_query()

一次仅支持一个语句。

事实上,这就是 mysql 客户端工具的工作原理 - 它通过分隔符分隔语句(默认分隔符是

;

,但可以更改),并一次执行一个语句。

要从 C 应用程序运行 SQL 脚本,您必须执行类似的操作。

如果您的 SQL 脚本还包含一些 mysql 客户端的内置命令,您必须在使用

mysql_query()

执行语句之前预先解析这些语句,并在 C 代码中复制这些命令的功能。

请记住,

;

字符可能出现在字符串文字或注释中。您必须在编写 C 代码来分割文件时牢记这一点。

如果某些 SQL 脚本包含创建存储例程的语句,则这些例程中可能包含 

;

字符,用于终止存储例程主体中的语句,而不是

CREATE
语句本身。这就是
DELIMITER
内置命令存在的原因,因此您可以将语句分隔符更改为
;
以外的其他内容。你也必须实现这个。
您还必须考虑字符集、NULL 值、网络数据包选项以及 mysql 客户端的许多其他功能。

我建议,如果你编写 C 代码来 fork 一个进程来运行 mysql 客户端来读取 SQL 脚本,这样更容易,更不容易出错,并且可以更快地完成你的任务。

© www.soinside.com 2019 - 2024. All rights reserved.