首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

C 語言操作 MySQL 完整教程:API 結構體、核心函數、實戰範例與編譯指南

     編輯:MySQL 綜合教學

C 語言操作 MySQL 完整教程:API 結構體、核心函數、實戰範例與編譯指南

在高效能、高安全性場景下,C 語言直接呼叫 MySQL C API (libmysqlclient) 是最佳選擇。本文系統介紹核心結構體、高頻函數原型、完整可編譯執行的查詢範例、GCC 編譯鏈結參數,助你快速上手 C/C++ 開發 MySQL 應用。

1. 兩大核心結構體

MYSQL — 連線控制結構

typedef struct st_mysql {
  NET net;                       // 通訊參數
  char *host, *user, *passwd, *unix_socket, *db;
  unsigned int port, client_flag, server_capabilities, protocol_version;
  unsigned int field_count;
  unsigned long thread_id;       // 連線 ID
  my_ulonglong affected_rows;    // 影響行數
  my_ulonglong insert_id;        // 自增 ID
  MYSQL_FIELD *fields;           // 結果集欄位資訊
  struct st_mysql_options options;
  // ... 省略其他欄位
} MYSQL;

用途:mysql_init() 初始化、mysql_real_connect() 建立連線、後續所有操作的句柄。

MYSQL_RES — 結果集結構

typedef struct st_mysql_res {
  my_ulonglong row_count;        // 總行數
  unsigned int field_count;      // 欄位數
  MYSQL_FIELD *fields;           // 欄位定義陣列
  MYSQL_DATA *data;              // 資料緩衝
  MYSQL_ROWS *data_cursor;       // 當前行游標
  MYSQL_ROW row;                 // 當前行資料(字串陣列)
  unsigned long *lengths;        // 各欄位長度
  MYSQL *handle;                 // 關聯連線
  my_bool eof;                   // 是否讀完
} MYSQL_RES;

用途:mysql_store_result() / mysql_use_result() 取得、mysql_fetch_row() 逐行讀取、mysql_free_result() 釋放。

2. 高頻函數速查表

函數功能關鍵參數 / 返回值
mysql_init(MYSQL *mysql)初始化/分配 MYSQL 結構返回初始化後指針,失敗返回 NULL
mysql_real_connect(MYSQL*, host, user, passwd, db, port, unix_socket, client_flag)真正建立 TCP/Unix Socket 連線成功返回 MYSQL*,失敗返回 NULL;client_flag 常用 CLIENT_MULTI_STATEMENTS 支援多語句/存儲過程
mysql_close(MYSQL *mysql)關閉連線並釋放記憶體無返回值
mysql_query(MYSQL *mysql, const char *sql)執行 SQL(不含二進位資料)成功返回 0,失敗非 0
mysql_real_query(MYSQL*, const char*, unsigned long)執行含二進位資料的 SQL同上
mysql_store_result(MYSQL *mysql)取得完整結果集至客戶端緩衝返回 MYSQL_RES*,失敗 NULL
mysql_use_result(MYSQL *mysql)無緩衝逐行讀取(串流)返回 MYSQL_RES*,需手動 fetch 完畢才能發下一條 SQL
mysql_fetch_row(MYSQL_RES *res)取得下一行(字串陣列 MYSQL_ROW)無更多行返回 NULL
mysql_num_fields(MYSQL_RES *res)取得欄位數返回 unsigned int
mysql_affected_rows(MYSQL *mysql)最近 INSERT/UPDATE/DELETE 影響行數返回 my_ulonglong;-1 表錯誤
mysql_insert_id(MYSQL *mysql)最近 AUTO_INCREMENT 生成的 ID返回 my_ulonglong
mysql_error(MYSQL *mysql)取得最近錯誤訊息字串返回 const char*
mysql_select_db(MYSQL*, const char *db)切換預設資料庫成功 0,失敗非 0
mysql_create_db / mysql_drop_db建立/刪除資料庫(舊 API,建議用 SQL)

3. 實戰範例:連線查詢並列印結果

場景:連線本地 9tmd_bbs_utf8 資料庫,查詢 tbb_user 表指定 userid 的 username。

#if defined(_WIN32) || defined(_WIN64)
#include 
#endif
#include 
#include 
#include "mysql.h"

#define SELECT_QUERY "SELECT username FROM tbb_user WHERE userid = %d"

int main(int argc, char **argv) {
  MYSQL mysql, *sock;
  MYSQL_RES *res;
  MYSQL_ROW row;
  char qbuf[160];

  if (argc != 2) {
    fprintf(stderr, "usage: %s \n", argv[0]);
    exit(1);
  }

  mysql_init(&mysql);
  // 關鍵:CLIENT_MULTI_STATEMENTS 支援 CALL 存儲過程/多語句
  if (!(sock = mysql_real_connect(&mysql, "localhost", "dbuser", "dbpwd",
                                  "9tmd_bbs_utf8", 0, NULL, CLIENT_MULTI_STATEMENTS))) {
    fprintf(stderr, "Connect failed: %s\n", mysql_error(&mysql));
    exit(1);
  }

  sprintf(qbuf, SELECT_QUERY, atoi(argv[1]));
  if (mysql_query(sock, qbuf)) {
    fprintf(stderr, "Query failed: %s\n", mysql_error(sock));
    exit(1);
  }

  if (!(res = mysql_store_result(sock))) {
    fprintf(stderr, "Store result failed: %s\n", mysql_error(sock));
    exit(1);
  }

  printf("Fields returned: %d\n", mysql_num_fields(res));
  while ((row = mysql_fetch_row(res))) {
    printf("User #%s name: %s\n", argv[1],
           (row[0] && strlen(row[0])) ? row[0] : "NULL");
    puts("Query OK");
  }

  mysql_free_result(res);
  mysql_close(sock);
  return 0;
}

4. GCC 編譯與鏈結指令

gcc -o mysql_select mysql_select.c \
  -I/usr/local/include/mysql \
  -L/usr/local/lib/mysql \
  -lmysqlclient -lz -lm
  • -I:指定 mysql.h 頭檔目錄
  • -L:指定 libmysqlclient.so 庫目錄
  • -lmysqlclient:鏈結 MySQL 客戶端庫
  • -lz -lm:部分系統需額外鏈結 zlib 與數學庫

5. 執行與輸出

$ ./mysql_select 1
Fields returned: 1
User #1 name: Michael
Query OK

6. 進階提示

  • 預處理語句:使用 mysql_stmt_prepare()、mysql_stmt_bind_param()、mysql_stmt_execute() 防 SQL 注入、提升重複執行效能。
  • 錯誤處理:每次 API 呼叫後檢查返回值,失敗時輸出 mysql_error()。
  • 字元集:連線建立後執行 mysql_set_character_set(sock, "utf8mb4") 或在 mysql_real_connect 前設 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4")。
  • 連線池:生產環境建議封裝連線池(如 libmysqlclient 無內建池,可參考 libdrizzle 或自行實現)。

掌握 C API 核心流程 init → real_connect → query → store_result → fetch_row → free_result → close,即可在嵌入式、高頻交易、系統級服務中發揮 MySQL 最大效能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved