首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C 語言存取 MySQL:取得資料庫所有資料表與欄位名稱完整實作

     編輯:關於C

需求場景

動態檢查 MySQL 資料庫結構:列出所有資料表,並取得每個資料表的所有欄位名稱。適用於資料庫遷移工具、ORM 框架建構、結構同步驗證等場景。

核心流程

  1. 連接 MySQL 伺服器
  2. 執行 `SHOW TABLES` 取得所有表名
  3. 對每個表執行 `SELECT * FROM table_name LIMIT 0`
  4. 使用 `mysql_fetch_fields` 取得欄位中繼資料
  5. 輸出表名與欄位列表

完整 C 程式碼

#include 
#include 
#include 
#include 

#define MAX_COUNT 256

void error_quit(const char *str, MYSQL *conn) {
    fprintf(stderr, "%s : %d: %s\n", str, mysql_errno(conn), mysql_error(conn));
    if (conn) mysql_close(conn);
    exit(1);
}

int main(int argc, char *argv[]) {
    MYSQL *conn = malloc(sizeof(MYSQL));
    MYSQL_RES *res;
    MYSQL_FIELD *fields;
    MYSQL_ROW row;
    int num_fields, i, j, ret;
    char tables[MAX_COUNT][MAX_COUNT] = {0};
    int table_count = 0;

    // 1. 初始化連接
    mysql_init(conn);
    conn = mysql_real_connect(conn, "127.0.0.1", "root", "password", 
                              "database_name", 0, NULL, CLIENT_FOUND_ROWS);
    if (!conn) error_quit("Connection failed", conn);
    printf("Connection success\n");

    // 2. 取得所有表名
    ret = mysql_query(conn, "SHOW TABLES");
    if (ret) error_quit("SHOW TABLES failed", conn);
    
    res = mysql_store_result(conn);
    if (!res) error_quit("Store result failed", conn);

    while ((row = mysql_fetch_row(res))) {
        if (row[0]) strcpy(tables[table_count++], row[0]);
    }
    mysql_free_result(res);

    // 3. 遍歷每個表,取得欄位
    for (i = 0; i < table_count; i++) {
        char query[256];
        snprintf(query, sizeof(query), "SELECT * FROM `%s` LIMIT 0", tables[i]);
        
        ret = mysql_query(conn, query);
        if (ret) error_quit("SELECT failed", conn);
        
        res = mysql_store_result(conn);
        if (!res) error_quit("Store result failed", conn);
        
        num_fields = mysql_num_fields(res);
        printf("Table: %s  Columns: %d\n", tables[i], num_fields);
        
        fields = mysql_fetch_fields(res);
        for (j = 0; j < num_fields; j++) {
            printf("  %s (%s)", fields[j].name, fields[j].type == MYSQL_TYPE_VAR_STRING ? "VARCHAR" : "OTHER");
        }
        printf("\n-------------------------------------\n\n");
        
        mysql_free_result(res);
    }

    mysql_close(conn);
    free(conn);
    return 0;
}

關鍵 API 解析

函數用途關鍵參數/回傳
mysql_real_connect建立連接host, user, passwd, db, port, unix_socket, client_flag
mysql_query執行 SQL0=成功, 非0=失敗
mysql_store_result取得完整結果集MYSQL_RES* (需 mysql_free_result)
mysql_fetch_row逐行取得資料MYSQL_ROW (字串陣列), NULL=結束
mysql_num_fields取得欄位數int
mysql_fetch_fields取得欄位中繼資料MYSQL_FIELD* 陣列
MYSQL_FIELD.name欄位名稱char*
MYSQL_FIELD.type欄位型別enum_field_types

優化建議

1. 使用 INFORMATION_SCHEMA (單查詢完成)

SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_database'
ORDER BY TABLE_NAME, ORDINAL_POSITION;
  • 單次查詢取得所有表結構,效率更高
  • 避免 N+1 查詢問題(N 個表 = N 次 SELECT)
  • 可直接取得型別、鍵、可空等完整資訊

2. 改用 mysql_use_result (串流模式)

  • `mysql_store_result`:一次性載入所有資料到記憶體
  • `mysql_use_result`:逐行串流讀取,記憶體佔用低
  • 對於 `SHOW TABLES` 或 `SELECT LIMIT 0` 結果集小,差異不明顯

3. 錯誤處理強化

// 檢查特定錯誤代碼
if (mysql_errno(conn) == ER_ACCESS_DENIED_ERROR) {
    fprintf(stderr, "認證失敗:帳號密碼錯誤\n");
} else if (mysql_errno(conn) == ER_BAD_DB_ERROR) {
    fprintf(stderr, "資料庫不存在\n");
}

編譯與執行

gcc get_schema.c -o get_schema -lmysqlclient
./get_schema

需安裝 MySQL 開發套件:`libmysqlclient-dev` (Ubuntu) 或 `mysql-devel` (CentOS)

執行範例輸出

Connection success
Table: class1  Columns: 4
  id (OTHER)  name (VARCHAR)  age (OTHER)  birthday (OTHER)
-------------------------------------

Table: students  Columns: 5
  id (OTHER)  name (VARCHAR)  gender (VARCHAR)  score (OTHER)  class_id (OTHER)
-------------------------------------

安全性注意事項

  • ❌ 程式碼中硬編碼密碼 → ✅ 使用環境變數/設定檔
  • ❌ 直接拼接 SQL → ✅ 表名無法參數化,需驗證合法性
  • ❌ 無連線池 → ✅ 生產環境使用連線池
  • ❌ 無 SSL → ✅ 生產環境啟用 `MYSQL_OPT_SSL_MODE`

這個工具展示了 C 語言透過 MySQL C API 進行資料庫中繼資料存取的標準模式,是建構資料庫工具的基礎組件。

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