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』。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章