MySQL学习笔记 | 06 - C语言嵌入SQL语句访问数据库

1. MySQL 头文件

#include<mysql.h>

2. MySQL 变量

① MYSQL_RES结构体:包含了查询结果集,也就是从数据库中获得的查询结果;

② MYSQL ROW:

typedef char **MYSQL_ROW;

它实际上是char **类型,指向一个字符串数组。
③ MYSQL_FIELD:

包含了字段名、字段类型和大小等信息,可以重复调用mysql_fetch_field函数获得所有字段的信息。

3. MySQL API

3.1. MySQL变量初始化

MYSQL *mysql_init(MYSQL *mysql);
  • 初始化的时候参数mysql可以写为NULL;
  • 成功则返回初始化成功的指针;
  • 失败返回NULL;

3.2. 连接MySQL数据库

MYSQL *mysql_real_connect(MYSQL *mysql, 
						const char *host,
						const char *user,
						const char *passwd, 
						const char *db,
						unsigned int port,
						const char *unix_socket,
						unsigned long client_flag);

其中参数意思为:

  • mysql:已初始化的MYSQL指针
  • host: MYSQL服务器的地址
  • user、 passwd:用户名、密码
  • db:要连接的数据库;
  • port: MYSQL服务器的TCP服务端口;
  • unix_socket: unix连接方式,为NULL时表示不使用socket或管道机制
  • clientflag: mysql运行为ODBC数据库的标记,一般取0

3.3. 执行MySQL命令

int mysql_query(MYSQL *mysql, const char*query);
  • mysql:前面定义的MYSQL变量
  • query: SQL语句(字符串)
  • 查询成功则该函数返回0;

3.4. 获取查询结果数据

① 获取查询结果数据:

MYSQL_RES * mysql_store_result(MYSQL *mysql);

该函数将从Mysql服务器查询的所有数据都存储到客户端,然后读取。

② 调用mysql_fetch_row函数读取结果集数据:

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
  • 参数result就是mysql_store_result或mysql_use_result的返回值;
  • 返回MYSQL_ROW型的变量,即字符串数组;
  • 假设返回的变量名为row,则row[i]为所查询数据表的第i个字段的值(从0开始);
  • 当到结果集尾部时,此函数返回NULL

③ 释放结果集:

void mysql_free_result(MYSQL_RES *result);

3.5. 关闭MySQL连接

不再查询mysql数据库时,调用 mysql_close 函数关闭数据库连接:

void mysql_close(MYSQL *mysql);

3.6. 返回错误代码

char *mysql_error(MYSQL *mysql);

3.7. 额外的API

① 显示MySQL客户端版本

mysql_get_client_info(MYSQL *mysql);

② 显示MySQL服务器信息

mysql_get_server_info(MYSQL *mysql);

③ 获取主机信息

Mysql_get_host_info(MYSQL *mysql);

4. 示例

/**
 * @brief   基于MySQL的用户电量管理系统
 * @author  Mculover666
 * @data    2020/04/22
*/
 
#include <stdio.h>
#include <mysql.h>
#include <my_global.h>
#include <string.h>

#define DATABASE    "wangshiwei"
#define TABLE       "user961"

void finish_with_error(MYSQL *con);
int get_value(MYSQL *con, const char* table, const char* field, const char* id, char* buf);
int set_value(MYSQL *con, const char* table, const char* field, const char* id, char* buf);

int main()
{
    int menu;
    MYSQL *con = NULL;
    char id[20] = {0};
    char buf[20] = {0};
    char sql[100];
    
    float balance = 0.0;
    int total = 0;

    /* 打印菜单 */
    printf("*********欢迎使用用户电量管理系统!***********\n");

    /* 初始化MYSQL变量并连接数据库 */
    con = mysql_init(NULL);
    if(con == NULL)
    {
        printf("MySQL init fail.\n");
        fprintf(stderr,"%s\n",mysql_error(con));
        return -1;
    }

    /* 连接数据库 */
    if(NULL == mysql_real_connect(con,"117.50.111.72","mculover666","mculover666","wangshiwei",3306,NULL,0))
    {
        printf("MySQL connect fail.\n");
        fprintf(stderr,"%s\n",mysql_error(con));
        mysql_close(con);
        return -1;
    }

    printf("远程数据库登录成功!\n");
    printf("请选择需要 1)查询; 2)更新\n");

    //接收用户输入
    scanf("%d", &menu);
    switch(menu)
    {
        case 1:
            /* 查询功能 */
            //打印菜单提供选择
            printf("请输入要查询的用户号:");
            //接收用户输入
            scanf("%s", id);
            //打印二级菜单进行选择
            printf("请选择需要查询的用户信息:\n");
            printf("--->1)用电类型; 2)余额; 3)总用电量\n");
            //接收用户输入
            scanf("%d", &menu);
            switch(menu)
            {
                case 1:
                    /* 查询用户用电类型信息并打印结果 */
                    if(-1 != get_value(con, TABLE, "type", id, buf))
                    {
                        printf("--->用户%s用电信息查询成功,当前用电类型为:%s\n", id, buf);
                    }
                    else
                    {
                        printf("***>用户%s用电信息查询失败!\n", id);
                        return -1;
                    }
                    break;
                case 2:
                    /* 查询用户用电余额并打印结果 */
                    if(-1 != get_value(con, TABLE, "balance", id, buf))
                    {
                        printf("--->用户%s用电信息查询成功,当前账户余额为:%s\n", id, buf);
                    }
                    else
                    {
                        printf("***>用户%s用电信息查询失败!\n", id);
                        return -1;
                    }
                    break;
                case 3:
                    /* 查询用户总用电量信息并打印结果 */
                    if(-1 != get_value(con, TABLE, "total", id, buf))
                    {
                        printf("--->用户%s用电信息查询成功,当前用电总量为:%s\n", id, buf);
                    }
                    else
                    {
                        printf("***>用户%s用电信息查询失败!\n", id);
                        return -1;
                    }
                    break;
                default:
                    /* 输入错误 */
                    printf("选项错误,系统推出!\n");
                    mysql_close(con);
                    return -1;
            }
            break;
        case 2:
            /* 更新功能 */
            //打印菜单提供选择
            printf("请输入要更新的用户号:");
            //接收用户输入
            scanf("%s", id);
            //打印二级菜单进行选择
            printf("请选择需要更新的用户信息:\n");
            printf("--->1)余额; 2)总用电量\n");
            //接收用户输入
            scanf("%d", &menu);
            switch(menu)
            {
                case 1:
                    /* 更新用户用电余额并打印结果 */
                    //接收用户输入的用电余额
                    printf("请输入新的用电余额:");
                    scanf("%f", &balance);
                    sprintf(buf, "%.2f", balance);
                    if(-1 != set_value(con, TABLE, "balance", id, buf))
                    {
                        printf("--->用户%s用电余额充值成功!\n", id);
                    }
                    else
                    {
                        printf("***>用户%s用电余额充值失败!\n", id);
                        return -1;
                    }
                    //执行完之后再次查询
                    if(-1 != get_value(con, TABLE, "balance", id, buf))
                    {
                        printf("--->用户%s用电信息查询成功,当前账户余额为:%s\n", id, buf);
                    }
                    else
                    {
                        printf("***>用户%s用电信息查询失败!\n", id);
                        return -1;
                    }
                    break;
                case 2:
                    /* 查询用户总用电量信息并打印结果 */
                    //接收用户输入的用电总量
                    printf("请输入新的用电总量:");
                    scanf("%d", &total);
                    sprintf(buf, "%d", total);
                    if(-1 != set_value(con, TABLE, "total", id, buf))
                    {
                        printf("--->抄表成功!用户%s用电总量更新成功!\n", id);
                    }
                    else
                    {
                        printf("***>抄表失败!用户%s用电总量更新失败!\n", id);
                        return -1;
                    }
                    //执行完之后再次查询
                    if(-1 != get_value(con, TABLE, "total", id, buf))
                    {
                        printf("--->用户%s用电信息查询成功,当前用电总量为:%s\n", id, buf);
                    }
                    else
                    {
                        printf("***>用户%s用电信息查询失败!\n", id);
                        return -1;
                    }
                    break;
                default:
                    /* 输入错误 */
                    printf("选项错误,系统推出!\n");
                    mysql_close(con);
                    return -1;
            }
            break;
        default:
            /* 输入错误 */
            printf("选项错误,系统推出!\n");
            mysql_close(con);
            return 0; 
    }
    mysql_close(con);
    return 0; 
}
/** 
 * 语句执行出错处理
 * @param con 需要处理的MYSQL变量
 * @return -1;
*/
void finish_with_error(MYSQL *con)
{
    fprintf(stderr,"%s\n",mysql_error(con));
    mysql_close(con);
}

/**
 * 从数据库中查询用户信息
 * @param con 成功连接的MySQL变量
 * @param table 需要查询的表
 * @param id 用户id
 * @param buf 存放查询结果的缓冲区
 * @return 成功返回0,失败则返回-1
*/
int get_value(MYSQL *con, const char* table, const char* field, const char* id, char* buf)
{
    char sql[100];
    MYSQL_RES *result = NULL;
    MYSQL_ROW row;

    //构造完整sql语句
    sprintf(sql, "select %s from %s where id=%11s;", field, table, id);
    //查询
    if(mysql_query(con,sql))
    {
        finish_with_error(con);
        return -1;
    }
    //获取并存储查询结果
    result = mysql_store_result(con);
    if(NULL == result)
    {
        finish_with_error(con);
        return -1;
    }
    //根据行数查询数据
    if(row = mysql_fetch_row(result))
    {
        if(row[0] != NULL)
        {
            strcpy(buf, row[0]);
        }
        else
        {
            strcpy(buf, "NULL");
        }
        //printf("用户%s的用电类型为:%s\n", id, );
    }
    mysql_free_result(result);

    return 0;
}
/**
 * 从数据库中更新用户信息
 * @param con 成功连接的MySQL变量
 * @param table 需要更新的表
 * @param id 用户id
 * @param buf 存放待更新数据的缓冲区
 * @return 成功返回0,失败则返回-1
*/
int set_value(MYSQL *con, const char* table, const char* field, const char* id, char* buf)
{
    char sql[100]; 
    
    //构造完整sql语句
    sprintf(sql, "update %s set %s=%s where id=%11s;", table, field, buf, id);
    //执行
    if(mysql_query(con,sql))
    {
        finish_with_error(con);
        return -1;
    }

    return 0;
}

编译:

gcc wangshiwei.c -I/usr/include/mysql -lmysqlclient -L/usr/lib/mysql -o wangshiwei

运行结果:

① 通过用户号查询该用户的与存款余额

② 通过用户号查询该用户的总用电量

③ 通过用户号查询该用户的用电类型

④ 用户充值(即通过用户号更新该用户的余额,更新后需要再次查询确认
充值成功)

⑤ 抄表(即通过用户号更新用电量,更新后需再次查询)

接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』。

发布了284 篇原创文章 · 获赞 1036 · 访问量 37万+

猜你喜欢

转载自blog.csdn.net/Mculover666/article/details/105680319