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

使用 C 語言操作 MySQL:連線、查詢、結果集處理完整範例

     編輯:MySQL 綜合教學

MySQL C API 核心流程

  1. mysql_init() 初始化連線結構
  2. mysql_real_connect() 建立 TCP/Unix Socket 連線
  3. mysql_query() 送出 SQL
  4. 非查詢類:mysql_affected_rows() 取得影響列數
  5. 查詢類:mysql_store_result() / mysql_use_result() 取得結果集 → mysql_fetch_row() 逐列處理 → mysql_free_result() 釋放
  6. mysql_close() 關閉連線

編譯連結


gcc -o myapp myapp.c $(mysql_config --cflags --libs)
# 或手動指定
-I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient

範例 1:非查詢操作 (INSERT/UPDATE/DELETE)


#include 
#include 
#include 
#include 

int main() {
    MYSQL mysql;
    mysql_init(&mysql);

    if (!mysql_real_connect(&mysql, "localhost", "user", "pass", "db", 0, NULL, 0)) {
        fprintf(stderr, "Connect failed: %s\n", mysql_error(&mysql));
        return EXIT_FAILURE;
    }

    // INSERT
    if (mysql_query(&mysql, "INSERT INTO children(fname,age) VALUES('Ann',3)")) {
        fprintf(stderr, "Insert error: %s\n", mysql_error(&mysql));
    } else {
        printf("Inserted %lu rows\n", (unsigned long)mysql_affected_rows(&mysql));
    }

    // UPDATE with CLIENT_FOUND_ROWS
    mysql_close(&mysql);
    mysql_init(&mysql);
    mysql_real_connect(&mysql, "localhost", "user", "pass", "db", 0, NULL, CLIENT_FOUND_ROWS);
    if (mysql_query(&mysql, "UPDATE children SET age=4 WHERE fname='Ann'")) {
        fprintf(stderr, "Update error: %s\n", mysql_error(&mysql));
    } else {
        printf("Updated %lu rows (matched)\n", (unsigned long)mysql_affected_rows(&mysql));
    }

    mysql_close(&mysql);
    return EXIT_SUCCESS;
}

關鍵點:

  • mysql_affected_rows() 回傳 my_ulonglong,列印用 %lu 強轉 unsigned long。
  • 預設 UPDATE 回傳實際改變列數;加上 CLIENT_FOUND_ROWS 回傳符合條件列數。
  • DELETE FROM t (無 WHERE) 為 Truncate 最佳化,回傳 0;用 DELETE FROM t WHERE 1>0 強制逐列刪除得真實計數。

範例 2:查詢操作 - 一次性取回所有結果


MYSQL_RES *res = mysql_store_result(&mysql);
if (!res) { /* 錯誤或無結果集 */ }

unsigned long num_rows = mysql_num_rows(res);
printf("Retrieved %lu rows\n", num_rows);

MYSQL_ROW row;
while ((row = mysql_fetch_row(res))) {
    // row 為 char** 陣列,row[i] 為欄位值 (NULL 時為 NULL 指標)
    for (int i = 0; i < mysql_num_fields(res); i++) {
        printf("%s\t", row[i] ? row[i] : "NULL");
    }
    printf("\n");
}

if (mysql_errno(&mysql)) {
    fprintf(stderr, "Fetch error: %s\n", mysql_error(&mysql));
}
mysql_free_result(res);

結果集導航函數:

  • mysql_data_seek(res, offset):跳到指定列號 (0-based)。
  • mysql_row_tell(res) / mysql_row_seek(res, offset):取得/設定內部列指標 (不等同列號)。

範例 3:查詢操作 - 串流式逐列取回


MYSQL_RES *res = mysql_use_result(&mysql);  // 不立即取回資料
if (!res) { /* 錯誤 */ }

MYSQL_ROW row;
while ((row = mysql_fetch_row(res))) {
    // 處理單列,記憶體佔用極低
    // 但此期間不可在同一連線執行其他查詢
}
mysql_free_result(res);
特性mysql_store_resultmysql_use_result
記憶體客戶端緩衝全部結果僅緩衝單列
網路一次傳完邊算邊傳
適用小/中結果集、需隨機存取超大結果集、串流處理
並發釋放伺服器資源快佔用伺服器資源久

錯誤處理模式


if (mysql_errno(&mysql)) {
    fprintf(stderr, "Error %u: %s\n", mysql_errno(&mysql), mysql_error(&mysql));
}

所有 API 呼叫後皆應檢查錯誤碼。

完整範例:查詢年齡 > 5 的兒童


#include 
#include 
#include 
#include 

int main() {
    MYSQL mysql;
    MYSQL_RES *res;
    MYSQL_ROW row;

    mysql_init(&mysql);
    if (!mysql_real_connect(&mysql, "localhost", "rick", "bar", "rick", 0, NULL, 0)) {
        fprintf(stderr, "Connect failed: %s\n", mysql_error(&mysql));
        return EXIT_FAILURE;
    }

    if (mysql_query(&mysql, "SELECT childno, fname, age FROM children WHERE age > 5")) {
        fprintf(stderr, "Select error: %s\n", mysql_error(&mysql));
    } else {
        res = mysql_store_result(&mysql);
        if (res) {
            printf("Retrieved %lu rows\n", (unsigned long)mysql_num_rows(res));
            while ((row = mysql_fetch_row(res))) {
                printf("ID: %s, Name: %s, Age: %s\n", row[0], row[1], row[2]);
            }
            mysql_free_result(res);
        }
    }
    mysql_close(&mysql);
    return EXIT_SUCCESS;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved