博客文章

C语言访问MySQL的一些乱七八糟的笔记

作者: andy.      时间: 2016-10-12 19:45:56

其实熟悉ADO.NET来看这个还是很简单的。

先来一个最简单的:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mysql/mysql.h>
 
int main(){
        MYSQL mysql, * connection;
        mysql_init(&mysql);//相当于SQL内部初始化了一个类似于TCP的socket,同时初始化了必须的内存和结构。
        connection = mysql_real_connect(&mysql, "localhost", "user1", "user1", "db1", 0, 0, 0);
        if(connection == NULL){
                perror("error");
                exit(-1);
        }
 
        mysql_close(connection);
 
        puts("complete");
}

接下来看一个修改数据的例子,先看看数据库中的数据:

blob.png

我们要修改ID为5的数据的名字,看代码:

int main(){
        system("stty erase ^H");

        MYSQL mysql, * connection;
        mysql_init(&mysql);
        connection = mysql_real_connect(&mysql, "localhost", "user1", "user1", "db1", 0, 0, 0);
        if(connection == NULL){
                printf(mysql_error(&mysql));
                exit(-1);
        }
        if(mysql_query(connection, "set names utf8;"))//先要设置为数据库的字符集,不然乱码
                printf(mysql_error(&mysql));

        char name[50];
        int name_length = read(STDIN_FILENO, name, 50);
        name[name_length - 1] = 0;

        char query_string[1024];
        memset(query_string, 0, 1024);
        sprintf(query_string, "update student set name = '%s' where ID = 5;", name);

        if(mysql_query(connection, query_string))
                printf(mysql_error(&mysql));

        mysql_close(connection);

        puts("nihao");
}

运行结果:

blob.pngblob.png

但是这种拼接字符串执行SQL语句会存在SQL注入的问题。其中,防止SQL注入的一个非常好的方法就是采用参数化SQL语句。

接下来介绍MySQL参数化SQL语句的方法。插入后获取自增ID、返回命令影响的数据条数也在这里一并介绍了,直接看代码吧,都是一些MYSQL封装好了直接的调用:

int main(){
        system("stty erase ^H");

        MYSQL mysql, * connection;
        mysql_init(&mysql);
        connection = mysql_real_connect(&mysql, "localhost", "user1", "user1", "db1", 0, 0, 0);
        if(connection == NULL){
                printf(mysql_error(&mysql));
                exit(-1);
        }
        if(mysql_query(connection, "set names utf8;"))
                printf(mysql_error(&mysql));

        MYSQL_STMT * stmt;
        MYSQL_BIND bind[2];//存参数
        memset(bind,0 ,sizeof(bind));
        
        stmt = mysql_stmt_init(connection);

        char query_string[1024];
        memset(query_string, 0, 1024);
        sprintf(query_string, "insert into student (name, age) values(?, ?);");

        if(mysql_stmt_prepare(stmt, query_string, strlen(query_string))){
                printf(mysql_error(&mysql));
                exit(-1);
        }

        bind[0].buffer_type = MYSQL_TYPE_STRING;//参数的赋值
        bind[0].buffer = "测试1";
        bind[0].buffer_length = strlen("测试1");

        int age = 123;
        bind[1].buffer_type = MYSQL_TYPE_LONG;
        bind[1].buffer = &age;
        bind[1].buffer_length = sizeof(int);

        if(mysql_stmt_bind_param(stmt, bind)){
                printf(mysql_error(&mysql));
                exit(-1);
        }

        if(mysql_stmt_execute(stmt)){//执行
                printf(mysql_error(&mysql));
                exit(-1);
        }

        printf("插入数据成功,更新数目为:%d\n", mysql_affected_rows(connection));//获取影响条数
        printf("自增ID为:%d\n", mysql_insert_id(connection));//获取插入的数据的自增ID

        mysql_stmt_close(stmt);
        mysql_close(connection);

        puts("nihao");
}

make一些直接执行,查看执行结果:

blob.png

select获得的数据如何输出,看代码:

int main(){
        system("stty erase ^H");

        MYSQL mysql, * connection;
        mysql_init(&mysql);
        connection = mysql_real_connect(&mysql, "localhost", "user1", "user1", "db1", 0, 0, 0);
        if(connection == NULL){
                printf(mysql_error(&mysql));
                exit(-1);
        }
        if(mysql_query(connection, "set names utf8;"))
                printf(mysql_error(&mysql));

        char query_string[1024];
        memset(query_string, 0, 1024);
        sprintf(query_string, "select * from student;");

        if(mysql_query(connection, query_string) != 0)
                printf(mysql_error(&mysql));

        MYSQL_RES * result = mysql_store_result(connection);//得到了查询结果,结果放在了result中。
        MYSQL_ROW row;
        while((row = mysql_fetch_row(result)) != NULL)
                printf("%s, %s, %s\n", row[0], row[1], row[2]);

        mysql_free_result(result);

        mysql_close(connection);

        puts("nihao");
}

上面通过mysql_store_result获得的输出结果,还有一种方法通过mysql_use_result来获得,区别:第一种把数据存在本地的,第二种把数据存在服务器上的。通过MYSQL_ROW逐条读出输出。

如果想要获得查出来的数据的字段可以通过MYSQL_FIELD * mysql_fetch_field(MYSQL_RES *result);获得每个字段的名称,用法和mysql_fetch_row相同,这里就不加累述了。