C 語言操作 MySQL 是後端儲存、嵌入式設備、高效能服務的常見選擇。本文匯總實戰中遇到的編譯鏈接配置、API 陷阱、錯誤碼分析與最佳實踐,作為快速查閱手冊。
INCLUDE = /usr/include/mysql
LIBS = /usr/lib/mysql
all:
gcc -I$(INCLUDE) -L$(LIBS) -lmysqlclient xxx.c -o xxx
clean:
rm -f xxx
| 安裝方式 | INCLUDE | LIBS |
|---|---|---|
| 系統預設 | /usr/include/mysql | /usr/lib/mysql |
| 原始碼安裝 /usr/local/mysql | /usr/local/mysql/include/mysql | /usr/local/mysql/lib/mysql |
錯誤:libmysqlclient.so.16: cannot open shared object file
ln -s /usr/local/mysql/lib/mysql/libmysqlclient.so.16 /usr/lib/libmysqlclient.so.16
# 或永久生效
echo "/usr/local/mysql/lib/mysql" >> /etc/ld.so.conf.d/mysql.conf
ldconfig
典型錯誤碼:呼叫順序錯誤。
// 錯誤示範
mysql_real_query(mysql, sql, strlen(sql));
num = mysql_affected_rows(mysql); // 未先取結果集
// 正確流程(查詢類)
mysql_real_query(mysql, sql, strlen(sql));
MYSQL_RES *res = mysql_store_result(mysql); // 或 mysql_use_result
num = mysql_num_rows(res);
// ... 處理資料 ...
mysql_free_result(res);
原則:mysql_real_query 後,**必須**呼叫 mysql_store_result/mysql_use_result 取得結果集指標,才能進一步操作。
INSERT INTO new_table (col1, col2, col3)
SELECT col1, col2, col3 FROM old_table WHERE condition;
MYSQL *mysql;
MYSQL_RES *res;
MYSQL_ROW row;
char *sql = "SELECT uid, uname FROM users WHERE uid=123";
mysql_real_connect(mysql, "host", "user", "pass", "db", 3306, NULL, 0);
mysql_real_query(mysql, sql, strlen(sql));
res = mysql_store_result(mysql);
row = mysql_fetch_row(res);
if (row) {
long uid = atol(row[0]);
char *uname = row[1] ? strdup(row[1]) : "";
// 使用 uid, uname
}
mysql_free_result(res);
mysql_close(mysql);
MYSQL_STMT *stmt = mysql_stmt_init(mysql);
const char *sql = "SELECT * FROM users WHERE uid=? AND status=?";
mysql_stmt_prepare(stmt, sql, strlen(sql));
MYSQL_BIND bind[2];
long uid = 123; int status = 1;
memset(bind, 0, sizeof(bind));
bind[0].buffer_type = MYSQL_TYPE_LONG; bind[0].buffer = &uid;
bind[1].buffer_type = MYSQL_TYPE_LONG; bind[1].buffer = &status;
mysql_stmt_bind_param(stmt, bind);
mysql_stmt_execute(stmt);
// ... bind_result + fetch ...
mysql_stmt_close(stmt);
libmysqlclient 內建或第三方)。mysql_error(mysql) 記錄日誌。mysql_free_result、mysql_stmt_close、mysql_close 必配對,防洩漏。SET NAMES utf8mb4,確保 Emoji/多語言支援。autocommit=0,COMMIT/ROLLBACK 顯式管理。MYSQL_STMT,杜絕拼接 SQL 注入風險。SET GLOBAL general_log=1;mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, ...) 捕獲截斷警告。mysql_store_result 未釋放)。C 操作 MySQL 核心在於**正確的編譯鏈接**、**嚴格遵循 API 呼叫順序**、**參數化查詢防注入**、**完善的錯誤與資源管理**。掌握上述要點,即可構建穩健高效的資料存取層。