mysql_init() 初始化連線結構mysql_real_connect() 建立 TCP/Unix Socket 連線mysql_query() 送出 SQLmysql_affected_rows() 取得影響列數mysql_store_result() / mysql_use_result() 取得結果集 → mysql_fetch_row() 逐列處理 → mysql_free_result() 釋放mysql_close() 關閉連線
gcc -o myapp myapp.c $(mysql_config --cflags --libs)
# 或手動指定
-I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient
#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。CLIENT_FOUND_ROWS 回傳符合條件列數。DELETE FROM t (無 WHERE) 為 Truncate 最佳化,回傳 0;用 DELETE FROM t WHERE 1>0 強制逐列刪除得真實計數。
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):取得/設定內部列指標 (不等同列號)。
MYSQL_RES *res = mysql_use_result(&mysql); // 不立即取回資料
if (!res) { /* 錯誤 */ }
MYSQL_ROW row;
while ((row = mysql_fetch_row(res))) {
// 處理單列,記憶體佔用極低
// 但此期間不可在同一連線執行其他查詢
}
mysql_free_result(res);
| 特性 | mysql_store_result | mysql_use_result |
|---|---|---|
| 記憶體 | 客戶端緩衝全部結果 | 僅緩衝單列 |
| 網路 | 一次傳完 | 邊算邊傳 |
| 適用 | 小/中結果集、需隨機存取 | 超大結果集、串流處理 |
| 並發 | 釋放伺服器資源快 | 佔用伺服器資源久 |
if (mysql_errno(&mysql)) {
fprintf(stderr, "Error %u: %s\n", mysql_errno(&mysql), mysql_error(&mysql));
}
所有 API 呼叫後皆應檢查錯誤碼。
#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;
}