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

C 語言操作 MySQL:C API 完整入門指南與範例代碼

     編輯:MySQL 綜合教學

C 語言操作 MySQL:C API 完整入門指南與範例代碼

MySQL 提供官方 C API(libmysqlclient),讓 C/C++ 程式能直接連線、查詢、管理資料庫。本文整理核心資料結構、常用函數表,並提供完整可編譯的範例程式。

核心資料結構

結構體用途關鍵說明
MYSQL連線控制代碼幾乎所有 API 函數的第一個參數,需先呼叫 mysql_init() 初始化
MYSQL_RES結果集儲存 SELECT、SHOW 等查詢回傳的完整結果,需呼叫 mysql_free_result() 釋放
MYSQL_ROW單列資料型別為 char **,由 mysql_fetch_row() 逐列取得,**非以 null 結尾**,含二進位資料時不可當字串處理
MYSQL_FIELD欄位中繼資料包含欄位名、型別、長度等,透過 mysql_fetch_field() 取得

常用 API 函數速查表(節選)

函數功能
mysql_init()初始化/取得 MYSQL 結構
mysql_real_connect()建立真實連線(取代舊版 mysql_connect())
mysql_real_query()執行 SQL(支援二進位資料,需傳長度)
mysql_store_result()將完整結果集讀入客戶端記憶體
mysql_use_result()啟動逐列串流讀取(省記憶體,但鎖表久)
mysql_fetch_row()取得下一列資料(傳回 MYSQL_ROW)
mysql_num_fields() / mysql_num_rows()取得欄位數/列數
mysql_free_result()釋放結果集記憶體
mysql_close()關閉連線
mysql_errno() / mysql_error()取得最後一次錯誤碼/訊息
mysql_affected_rows()取得 INSERT/UPDATE/DELETE 影響列數
mysql_insert_id()取得 AUTO_INCREMENT 生成的 ID
mysql_options()設定連線選項(字元集、超時、SSL 等)
mysql_ping()檢查連線存活,必要時自動重連
mysql_autocommit() / mysql_commit() / mysql_rollback()事務控制

完整範例:查詢資料表並列印結果

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

int main() {
    MYSQL mysql;
    MYSQL_RES *res;
    MYSQL_ROW row;
    char *query = "SELECT id, name, age FROM students";

    mysql_init(&mysql);
    // 連線參數:host, user, passwd, db, port, unix_socket, client_flag
    if (!mysql_real_connect(&mysql, "localhost", "root", "password", "testdb", 0, NULL, 0)) {
        fprintf(stderr, "連線失敗: %s\n", mysql_error(&mysql));
        return EXIT_FAILURE;
    }
    printf("連線成功\n");

    if (mysql_real_query(&mysql, query, (unsigned long)strlen(query))) {
        fprintf(stderr, "查詢失敗: %s\n", mysql_error(&mysql));
        mysql_close(&mysql);
        return EXIT_FAILURE;
    }

    res = mysql_store_result(&mysql);
    if (!res) {
        fprintf(stderr, "取得結果集失敗: %s\n", mysql_error(&mysql));
        mysql_close(&mysql);
        return EXIT_FAILURE;
    }

    // 列印欄位名
    unsigned int num_fields = mysql_num_fields(res);
    MYSQL_FIELD *fields = mysql_fetch_fields(res);
    for (unsigned int i = 0; i < num_fields; i++) {
        printf("%s\t", fields[i].name);
    }
    printf("\n");

    // 逐列列印
    while ((row = mysql_fetch_row(res))) {
        for (unsigned int i = 0; i < num_fields; i++) {
            printf("%s\t", row[i] ? row[i] : "NULL");
        }
        printf("\n");
    }

    mysql_free_result(res);
    mysql_close(&mysql);
    return EXIT_SUCCESS;
}

編譯與連結

# 取得編譯旗標與連結庫
mysql_config --cflags --libs
# 輸出範例:-I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient

gcc -o mysql_demo mysql_demo.c $(mysql_config --cflags --libs)

常見坑點與最佳實務

  • 記憶體洩漏:每個 mysql_store_result() 必須配對 mysql_free_result()。
  • 二進位資料:含 NULL byte 的欄位(如 BLOB)不可用 strlen(),需搭配 mysql_fetch_lengths() 取得真實長度。
  • 字元集:連線後立即執行 SET NAMES utf8mb4 或呼叫 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4")。
  • 執行緒安全:若多執行緒共用連線,需自行加鎖;建議每執行緒獨立連線,或使用連線池。
  • 預處理陳述式:重複執行的 SQL 請使用 mysql_stmt_prepare() 系列 API,防止 SQL Injection 並提升效能。

編譯執行畫面

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