当使用SELECT语句等的时候,想要打印信息,这里提供三种方式
1. 使用sqlite_exec的回调函数。
sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)
第四个参数data是callback的第一个参数。
int displaycb(void *para,int ncolumn,char ** columnvalue,char *columnname[])
{
for(int i = 0; i < ncolumn; i++)
{
printf("key:%s----> value:%s\n",columnname[i],columnvalue[i]);
}
return 0;
}
2. 使用sqlite3_get_table去获取信息,将二维数组内容打印
int sql_search_info(char* sql) {
int len;
int i = 0;
int nrow = 0;
int ncolumn = 0;
char* zErrMsg = NULL;
char** azResult = NULL; //二维数组存放结果
sqlite3_get_table(g_db, sql, &azResult, &nrow, &ncolumn, &zErrMsg);
if (nrow == 0) {
printf("cannot find data\n");
return -1;
}
char label[512] = { 0 };
for (int i = 0; i <= 16 * ncolumn; i++)
sprintf(label + strlen(label), "-");
printf("%s\n", label);
for (i = 0; i < (nrow + 1) * ncolumn; i++)
{
printf("|%-8s\t", azResult[i]);
if ((i + 1) % ncolumn == 0) {
printf("|\n");
printf("%s\n", label);
}
}
return 0;
};
3. 使用sqlite3_prepare_v2 => sqlite3_column_count => sqlite3_step => sqlite3_finalize 等一系列函数
int sql_search_lol_info() {
champion cham;
memset(&cham, 0, sizeof(champion));
int ID = 0;
char uptime[32] = { 0 };
char formtime[32] = { 0 };
char* sql = sqlite3_mprintf("select * from LOL");
sqlite3_stmt* stmt = NULL;
int ncolumn = 0;
const char* column_name;
int vtype, i;
int rc;
rc = sql_prepare(sql, &stmt); //调用函数在下面
if (0 == rc) {
ncolumn = sqlite3_column_count(stmt);
while (sqlite3_step(stmt) == SQLITE_ROW) {
for (i = 0; i < ncolumn; i++) {
vtype = sqlite3_column_type(stmt, i);
column_name = sqlite3_column_name(stmt, i);
switch (vtype) {
case SQLITE_INTEGER:
if (!strcmp("id", column_name))
ID = sqlite3_column_int(stmt, i);
if (!strcmp("age", column_name))
cham.age = sqlite3_column_int(stmt, i);
break;
case SQLITE_FLOAT:
if (!strcmp("difficulty", column_name))
cham.diff = (float)sqlite3_column_double(stmt, i);
break;
case SQLITE_TEXT:
if (!strcmp("name", column_name))
strcpy(cham.name, (const char*)sqlite3_column_text(stmt, i));
if (!strcmp("organization", column_name))
strcpy(cham.org, (const char*)sqlite3_column_text(stmt, i));
if (!strcmp("role", column_name))
strcpy(cham.role, (const char*)sqlite3_column_text(stmt, i));
if (!strcmp("weapon", column_name))
strcpy(cham.weapon, (const char*)sqlite3_column_text(stmt, i));
}
break;
case SQLITE_BLOB:
break;
case SQLITE_NULL:
break;
default:
break;
}
}
printf("%-4d %-8s %-4d %-8s %-8s %-16s %-4f\n", ID, cham.name, cham.age, cham.org, cham.role, cham.weapon, cham.diff);
}
}
sqlite3_finalize(stmt);
return 0;
}
int sql_prepare(const char* sql, sqlite3_stmt** stmt) {
if (NULL == sql || NULL == stmt) {
printf("param error");
return -1;
}
if (NULL == g_db) {
printf("_g_db error");
return -1;
}
if (SQLITE_OK != sqlite3_prepare_v2(g_db, sql, -1, stmt, 0)) {
printf("sqlite3_prepare_v2 error");
return -1;
}
return 0;
}
对比:
使用get_table有时候会出问题,虽然我没有遇到过,但是当默写特殊情况发生,会导致错误。附上一个我找到的原因。
至于使用回调函数和第三种,虽然第三种麻烦了点,不过这也是官方推荐的方式。而且更方便控制。所以我推荐使用第三种方式。