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

C 語言操作 MySQL:獲取資料庫所有資料表與欄位資訊完整實戰

     編輯:關於C語言

應用場景

  • 資料庫結構自動文件化
  • ORM 框架建立模型類別
  • 異構資料庫遷移工具
  • 開發期除錯:快速檢視 Schema

核心流程

  1. 初始化 MYSQL 連線控制結構
  2. mysql_real_connect 建立連線
  3. 執行 SHOW TABLES 獲取所有表名
  4. 迴圈每個表:SELECT * FROM table LIMIT 0 取得 MYSQL_FIELD 陣列
  5. 解析 MYSQL_FIELD 取得欄位名、型別、長度等中繼資料
  6. 釋放結果集、關閉連線、釋放記憶體

完整程式碼

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

#define MAX_TABLES 256
#define MAX_NAME_LEN 256

void error_quit(const char *msg, MYSQL *conn) {
    fprintf(stderr, "%s: %u - %s\n", msg, mysql_errno(conn), mysql_error(conn));
    if (conn) mysql_close(conn);
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
    MYSQL *conn = mysql_init(NULL);
    if (!conn) error_quit("mysql_init 失敗", NULL);

    /* 連線參數建議從環境變數/設定檔讀取 */
    if (!mysql_real_connect(conn, "127.0.0.1", "root", "password", 
                            "testdb", 3306, NULL, CLIENT_FOUND_ROWS)) {
        error_quit("連線失敗", conn);
    }
    printf("連線成功\n");

    /* 1. 獲取所有表名 */
    if (mysql_query(conn, "SHOW TABLES")) error_quit("SHOW TABLES 失敗", conn);
    MYSQL_RES *res = mysql_store_result(conn);
    if (!res) error_quit("獲取結果集失敗", conn);

    char tables[MAX_TABLES][MAX_NAME_LEN];
    int table_count = 0;
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(res)) && table_count < MAX_TABLES) {
        if (row[0]) strncpy(tables[table_count++], row[0], MAX_NAME_LEN - 1);
    }
    mysql_free_result(res);

    /* 2. 逐表獲取欄位資訊 */
    for (int i = 0; i < table_count; i++) {
        char query[512];
        snprintf(query, sizeof(query), "SELECT * FROM `%s` LIMIT 0", tables[i]);
        
        if (mysql_query(conn, query)) error_quit("SELECT 失敗", conn);
        res = mysql_store_result(conn);
        if (!res) error_quit("獲取欄位結果失敗", conn);

        int field_count = mysql_num_fields(res);
        MYSQL_FIELD *fields = mysql_fetch_fields(res);
        
        printf("表: %-20s 欄位數: %d\n", tables[i], field_count);
        for (int j = 0; j < field_count; j++) {
            printf("  %-20s  型別: %3d  長度: %lu  標誌: 0x%lx\n",
                   fields[j].name, fields[j].type, fields[j].length, fields[j].flags);
        }
        printf("--------------------------------------------------\n");
        mysql_free_result(res);
    }

    mysql_close(conn);
    return 0;
}

編譯與連結

# Ubuntu/Debian
sudo apt-get install libmysqlclient-dev
gcc -o db_inspect db_inspect.c $(mysql_config --cflags --libs)

# 或手動
gcc -o db_inspect db_inspect.c -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient

關鍵 API 與資料結構

API/結構用途
MYSQL連線控制結構
mysql_init()初始化/分配 MYSQL 結構
mysql_real_connect()建立 TCP/Unix socket 連線
mysql_query()發送 SQL 指令
mysql_store_result()將完整結果集讀取到客戶端記憶體
mysql_fetch_row()逐列取得資料列(char**)
mysql_num_fields()取得欄位數
mysql_fetch_fields()取得 MYSQL_FIELD 陣列(中繼資料)
MYSQL_FIELD欄位資訊:name, type, length, flags, decimals 等

MYSQL_FIELD 關鍵欄位

typedef struct st_mysql_field {
    char *name;           // 欄位名
    char *org_name;       // 原始欄位名(別名前)
    char *table;          // 表名
    char *org_table;      // 原始表名
    char *db;             // 資料庫名
    char *catalog;        // 目錄名
    char *def;            // 預設值
    unsigned long length; // 最大長度
    unsigned long max_length; // 實際最大長度
    unsigned int name_length;
    unsigned int org_name_length;
    unsigned int table_length;
    unsigned int org_table_length;
    unsigned int db_length;
    unsigned int catalog_length;
    unsigned int def_length;
    unsigned int flags;   // NOT_NULL, PRI_KEY, AUTO_INCREMENT 等
    unsigned int decimals; // 數值小數位
    unsigned int charsetnr; // 字符集編號
    enum enum_field_types type; // 型別:MYSQL_TYPE_LONG, VARCHAR 等
} MYSQL_FIELD;

進階:使用 INFORMATION_SCHEMA 獲取更豐富中繼資料

/* 替代 SHOW TABLES + SELECT * LIMIT 0 */
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, COLUMN_TYPE, 
       IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, EXTRA,
       CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'testdb'
ORDER BY TABLE_NAME, ORDINAL_POSITION;

優點:單一查詢獲取所有表的完整欄位定義,包含預設值、自增、註解等 SHOW COLUMNS 才有的資訊。

錯誤處理最佳實踐

  • 每個 API 呼叫後檢查回傳值
  • 使用 mysql_errno() / mysql_error() 獲取詳細錯誤
  • 區分連線錯誤(CR_*)、SQL 錯誤(ER_*)
  • 生產環境建議使用連線池與預處理語句
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved