C 語言調用 MySQL C API 實現 SELECT 查詢完整教程
編譯命令
gcc mysql_select.c -o test -I /usr/include/mysql -L /usr/lib -lmysqlclient
完整源碼
// mysql_select.c
#include <stdio.h>
#include <string.h>
#include <mysql/mysql.h>
#define HOST "localhost"
#define USERNAME "SERVER"
#define PASSWORD "SERVER_PASSWORD"
#define DATABASE "remote_control"
int main() {
char *sql = "SELECT * FROM users";
int res;
int i, j;
int row, column;
MYSQL my_connection;
MYSQL_RES *res_ptr;
MYSQL_FIELD *field;
MYSQL_ROW result_row;
// 1. 初始化連接句柄
mysql_init(&my_connection);
// 2. 建立真實連接
if (!mysql_real_connect(&my_connection, HOST, USERNAME, PASSWORD,
DATABASE, 3306, NULL, CLIENT_FOUND_ROWS)) {
fprintf(stderr, "連接失敗: %s\n", mysql_error(&my_connection));
return 1;
}
// 3. 設置字符集
mysql_query(&my_connection, "SET NAMES utf8");
// 4. 執行查詢
res = mysql_real_query(&my_connection, sql, (unsigned int)strlen(sql));
if (res) {
fprintf(stderr, "查詢失敗: %s\n", mysql_error(&my_connection));
mysql_close(&my_connection);
return 1;
}
// 5. 獲取結果集
res_ptr = mysql_store_result(&my_connection);
if (!res_ptr) {
printf("結果集為空\n");
mysql_close(&my_connection);
return 0;
}
// 6. 解析元數據
column = mysql_num_fields(res_ptr);
row = mysql_num_rows(res_ptr);
printf("查詢到 %d 行\n", row);
// 打印列名
for (i = 0; (field = mysql_fetch_field(res_ptr)); i++)
printf("%s ", field->name);
printf("\n");
// 7. 逐行讀取數據
for (i = 0; i < row; i++) {
result_row = mysql_fetch_row(res_ptr);
for (j = 0; j < column; j++)
printf("%s ", result_row[j] ? result_row[j] : "NULL");
printf("\n");
}
// 8. 釋放資源
mysql_free_result(res_ptr);
mysql_close(&my_connection);
return 0;
}
關鍵 API 流程圖解
mysql_init() → 初始化 MYSQL 結構體
mysql_real_connect() → TCP/Unix Socket 連接,驗證身份
mysql_real_query() → 發送 SQL,非阻塞
mysql_store_result() → 將**完整結果集**讀取到客戶端內存(適合中小結果集)
大結果集改用 mysql_use_result() 流式讀取
mysql_num_fields/rows() → 獲取列數/行數
mysql_fetch_field() → 遍歷列定義(名、類型、長度等)
mysql_fetch_row() → 逐行獲取 MYSQL_ROW(字符串數組)
mysql_free_result() → 釋放結果集內存
mysql_close() → 關閉連接
常見坑點
- 編譯需链接
-lmysqlclient,頭文件路徑 -I/usr/include/mysql
MYSQL_ROW 是 char**,**所有值均為字符串**,需自行轉型
NULL 值在 MYSQL_ROW 中表現為 NULL 指針,打印前需判斷
- 長連接需處理
mysql_ping() 心跳與自動重連
- 生產環境建議使用連接池(如自建或第三方庫)