動態檢查 MySQL 資料庫結構:列出所有資料表,並取得每個資料表的所有欄位名稱。適用於資料庫遷移工具、ORM 框架建構、結構同步驗證等場景。
#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;
}
| 函數 | 用途 | 關鍵參數/回傳 |
|---|---|---|
| mysql_real_connect | 建立連接 | host, user, passwd, db, port, unix_socket, client_flag |
| mysql_query | 執行 SQL | 0=成功, 非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 |
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;
// 檢查特定錯誤代碼
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) -------------------------------------
這個工具展示了 C 語言透過 MySQL C API 進行資料庫中繼資料存取的標準模式,是建構資料庫工具的基礎組件。