1. 程式人生 > >sqlite_exec回撥函式的使用

sqlite_exec回撥函式的使用

在學習sqlite3小型資料庫的時候,發現了sqlite3_exec的函式,可以呼叫回撥函式

具體的原型如下:

原型:int sqlite3_exec(sqlite3* pDB, const char *sql, sqlite_callback callback, void*para, char** errMsg);
功能:編譯和執行零個或多個SQL 語句,查詢的結果返回給回撥函式callback
輸入引數:
pDB,資料庫控制代碼
sql,待執行的SQL 語句字串,以’\0’結尾
callback,回撥函式,用來處理查詢結果,如果不需要回調(比如做insert 或者delete 操作時),可以輸入NULL

輸出引數:errMsg,返回錯誤資訊,注意是指標的指標。
返回值:執行成功返回SQLITE_OK,否則返回其他值

回撥函式的原型如下:

回撥函式:
原型:typedef int (*sqlite_callback)(void* para,int columnCount,char** columnValue,char** columnName);
功能:由使用者處理查詢的結果
引數:
para,從sqlite3_exec()傳入的引數指標;
columnCount, 查詢到的這一條記錄有多少個欄位(即這條記錄有多少列);
columnValue,查詢出來的資料都儲存在這裡,它實際上是個1 維陣列(不要以為是2 維陣列),每一個元素都是一個char * 值,是一個欄位內容(用字串來表示,以‘\0’結尾);
columnName,與columnValue 是對應的,表示這個欄位的欄位名稱。
返回值:執行成功返回SQLITE_OK,否則返回其他值

然後編寫了一段測試程式來測試回撥函式:

#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>
 
void create_table(sqlite3 *db)
{
    char *sql;
    char *errmsg;
    int ret;
 
	sql = "create table if not exists mytable (id integer primary key,name text);";
 
	ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
 
	if(ret != SQLITE_OK)
	{
		printf("create table error : %s\n",errmsg);
		exit(-1);
	}
}
 
void insert_record(sqlite3 *db)
{
    char sql[100];
    char *errmsg;
    int ret;
	int id;
	char name[20];
 
	printf("please input id and name:\n");
 
	scanf("%d%s",&id,name);
 
	sprintf(sql,"insert into mytable (id,name)values(%d,'%s');",id,name);
 
	ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
 
	if(ret != SQLITE_OK)
	{
		printf("insert record  error : %s\n",errmsg);
		exit(-1);
	}
#if 0	
	sql = "insert into mytable (id,name)values(NULL,'zhang');";
 
	ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
 
	if(ret != SQLITE_OK)
	{
		printf("insert record  error : %s\n",errmsg);
		exit(-1);
	}
	
	sql = "insert into mytable (id,name)values(NULL,'lin');";
 
	ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
 
	if(ret != SQLITE_OK)
	{
		printf("insert record  error : %s\n",errmsg);
		exit(-1);
	}
#endif
}
 
int displaycb(void *para,int ncolumn,char ** columnvalue,char *columnname[])
{
	int i;nam
	printf("total column is %d\n",ncolumn);
 
	for(i = 0;i < ncolumn; i++)
	{
		printf("col_name:%s----> clo_value:%s\n",columnname[i],columnvalue[i]);
	}
	printf("===========================\n");
 
	return 0;
}
 
void inquire_usecb(sqlite3 * db)
{
    char *sql;
    char *errmsg;
    int ret;
 
	sql = "select * from mytable;";
 
	ret = sqlite3_exec(db,sql,displaycb,NULL,&errmsg);
 
	if(ret != SQLITE_OK)
	{
		printf("select error : %s\n",errmsg);
		exit(-1);
	}
 
}
 
void inquire_nocb(sqlite3 *db)
{
    int nrow,ncolumn;
	char **azresult;
	char *sql;
	char *errmsg;
	int ret;
	int i;
 
	sql = "select * from mytable;";
 
    ret = sqlite3_get_table(db,sql,&azresult,&nrow,&ncolumn,&errmsg);
 
    if(ret != SQLITE_OK)
	{
		printf("get table error:%s",errmsg);
		exit(-1);
	}
 
	printf("nrow = %d,column = %d\n",nrow,ncolumn);
;
 
	sqlite3_free_table(azresult);
}
 
int main()
{
	sqlite3 *db;
	int ret;
 
	ret = sqlite3_open("mydatabase.db",&db);
 
	if(ret != SQLITE_OK)
	{
		printf("open database error : %s\n",sqlite3_errmsg(db));
		exit(-1);
	}
  else
	{
		printf("you have opened a database succefully!\n");
	}
 
	create_table(db);
	insert_record(db);
	inquire_usecb(db);
     // inquire_nocb(db);
 
	sqlite3_close(db);
    return 0;
}
int displaycb(void *para,int ncolumn,char ** columnvalue,char *columnname[])
{
	int i;nam
	printf("total column is %d\n",ncolumn);
 
	for(i = 0;i < ncolumn; i++)
	{
		printf("col_name:%s----> clo_value:%s\n",columnname[i],columnvalue[i]);
	}
	printf("===========================\n");
 
	return 0;
}

這部分程式所說:for迴圈呼叫了兩次,分別打印出了id列和name列,怎麼就一下子全部把資料打印出來了呢

經過討論和查閱資料發現,其實是sqlite3_exec在查詢表的時候,每查到一條記錄,就會呼叫一次回撥函式,所以才是會顯示出所有資料