使用 sqlite3_get_table 執行查詢後,結果存放於 char **azResult,回傳值 rc 為 SQLITE_OK (0) 表示執行成功,不代表有資料。需檢查 nRow (行數) 與 nCol (欄數) 判斷是否有結果。
int sqlite3_get_table(
sqlite3 *db,
const char *sql,
char ***azResult, // 輸出:二維陣列指標
int *nRow, // 輸出:資料行數 (不含標題行)
int *nCol, // 輸出:欄數
char **errMsg // 輸出:錯誤訊息
);
azResult[0] ~ azResult[nCol-1]:欄位名稱 (標題行)。azResult[nCol] ~ azResult[(nRow+1)*nCol - 1]:資料行,按行優先序排列。nRow == 0,azResult 僅含標題行 (或為 NULL 視版本而定)。char **azResult = NULL;
int nRow = 0, nCol = 0;
char *errMsg = NULL;
int rc = sqlite3_get_table(db, sql, &azResult, &nRow, &nCol, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", errMsg);
sqlite3_free(errMsg);
} else {
if (nRow > 0) {
// 有資料
for (int i = 0; i < nRow; ++i) {
for (int j = 0; j < nCol; ++j) {
char *val = azResult[(i + 1) * nCol + j];
printf("%s\t", val ? val : "NULL");
}
printf("\n");
}
} else {
printf("查無資料\n");
}
sqlite3_free_table(azResult); // 必須釋放!
}
rc == 0 判斷有資料 → 錯誤,查無資料也回傳 0。sqlite3_free_table(azResult) → 記憶體洩漏。azResult[i] 未檢查 NULL → 某欄位為 NULL 時會崩潰,需三元運算 val ? val : "NULL"。static int callback(void *data, int argc, char **argv, char **colName) {
for (int i = 0; i < argc; ++i) printf("%s=%s ", colName[i], argv[i] ? argv[i] : "NULL");
printf("\n");
return 0;
}
sqlite3_exec(db, sql, callback, NULL, &errMsg);
回呼模式逐行處理,不佔用大記憶體,適合百萬行以上查詢。