【SQLite_7】sqlite3_get_table()函数

  1. {  
  2.  sqlite3 *db;  
  3.  char *errmsg=NULL;    //用来存储错误信息字符串  
  4.  char ret=0;  
  5.  int my_age=0;    //类型根据要提取的数据类型而定  
  6.  char **dbResult;  
  7.  int nRow=0, nColumn=0;     //nRow 查找出的总行数,nColumn 存储列  
  8.   
  9.  ret = sqlite3_open("student.db",&db);  
  10.  if(1 == ret)     //数据库创建未成功  
  11.  {  
  12.   fprintf(stderr, "Can't open this database: %s\n"sqlite3_errmsg(db));    //用sqlite3_errmsg()得到错误字符串  
  13.   sqlite3_close(db);  
  14.   return -1;  
  15.  }  
  16.   
  17.  ret=sqlite3_get_table(db, "select * from age;", &dbResult, &nRow, &nColumn, &errmsg);  
  18.   
  19.  if(NULL!=errmsg)  
  20.  {  
  21.   sqlite3_free_table(dbResult);  
  22.   errmsg=NULL;  
  23.   return -1  
  24.  }  
  25.   
  26.  my_age = atoi(dbResult[nColumn]);  
  27.  sqlite3_free_table(dbResult);  
  28.  return 0;  
  29. }  

sqlite3 *db创建数据库类型的指针,通过sqlite3_open()函数使db指针指向该数据库。

注意:

1、 char **dbResult; 字符型的二重指针将数据库里sqlite3_get_table()出来的数据以字符的方式给dbResult

2、select * from age;查询student数据库里的age表全部内容。

3、my_age = atoi(dbResult[nColumn]);将查询出来给dbResult的数据(字符)通过aoti()转换成整型交给变量my_age供程序中直接应用

重点:(假设age表里有n个字段)

1、通过select * from age;给dbResult的字符前n个(0,n)为字段名称(只有计算机认识),dbResult[n]以后分别代表字段的值(包括dbResult[n])。如图

           *      *      *      * .........*  (dbResult[0]~[n-1]分别代表字段名)

  dbResult[n]   [n+1]  [n+2]  [n+3].....[n+n-1] (dbResult[n]~[n+n-1]分别代表第一条记录的值)

  dbResult[2n]  [2n+1] [2n+2] [2n+3]....[2n+n-1](dbResult[2n]~[2n+n-1]分别代表第二条记录的值)

  dbResult[3n]  [3n+1] [3n+2] 32n+3]....[3n+n-1](dbResult[3n]~[3n+n-1]分别代表第三条记录的值)

注:sqlite3_get_table()之后便将以上的n(字段数:简称列)给了nColumn这个变量,可直接应用。nRow变量代表共有多少条记录,可直接应用。

2、通过select * from age where id=0;如果查到0条记录的话nRow等于0,查到1条记录的话nRow等于1,假设查到1条数据,举例:

           *      *      *      * .........*  (dbResult[0]~[n-1]分别代表字段名)

  dbResult[n]   [n+1]  [n+2]  [n+3].....[n+n-1] (dbResult[n]~[n+n-1]分别代表第一条记录的值)

注:此时dbResult[]只有0~2n-1共2n个字符,此时如果对dbResult[2n]引用的话就会出错。查询两条语句的话以此类推。

           *      *      *      * .........*  (dbResult[0]~[n-1]分别代表字段名)

  dbResult[n]   [n+1]  [n+2]  [n+3].....[n+n-1] (dbResult[n]~[n+n-1]分别代表第一条记录的值)

  dbResult[2n]  [2n+1] [2n+2] [2n+3]....[2n+n-1](dbResult[2n]~[2n+n-1]分别代表第二条记录的值)

注:此时dbResult[]只有0~3n-1可引用。

sqlite3_get_table执行查询速度会变慢的问题

10-10

大家好,我自己写了一个sqlite3_get_table函数的封装,在作测试的时候,发现这个函数在使用时,查询的速度会变慢。具体的封装是这样的rnrn/*db_name is the database you want to open and sql is the sql sentence to execute, thisrn**sql sentence must be sql select sentence***************************/rnint SQL_Select(const char* db_name, const char* sql, char ***pResult, int *nRow, int *nCol)rnrn if(NULL == db_name || NULL == sql)rn return false;rnrn sqlite3 *db = NULL; //the database to be openedrnrn if((db = OpenDB(db_name)) == NULL)rn rn return false;rn rn//execute select sentencern if(false == SelectFromTable(db, sql, pResult, nRow, nCol))rn rn return false;rn rnrn CloseDB(db);rnrn return true;rnrnrn这里的OpenDB和CloseDB函数分别是对sqlite3_open和sqlite3_close函数的封装。SelectFromTable(db, sql, pResult, nRow, nCol)函数封装了sqlite3_get_table函数rn这个函数的代码是这样的rnstatic bool SelectFromTable(sqlite3* db,const char *sql, char ***pResult, int *nRow, int *nCol)rnrn if(sql == NULL || db == NULL)rn return false;rnrn char *errr_msg = NULL;rn// char *zErr; // lxx addrn int rc;rn api.sqlite3_exec(db,"BEGIN",NULL,NULL,&zErr);rn rc = (api.sqlite3_get_table)(db,sql,pResult, nRow, nCol, &errr_msg);rn api.sqlite3_exec(db,"COMMIT",NULL,NULL,&zErr);rn if(rc != SQLITE_OK)rn rn if(NULL != errr_msg)rn rn #ifdef DEBUGrn printf("SQL error: %s\n",errr_msg);rn #endifrn (api.sqlite3_free)(errr_msg);rn errr_msg = NULL;rn //end ifrn if(NULL != *pResult)rn rn (api.sqlite3_free_table)(*pResult);rn pResult = NULL;rn rn return false;rn //end ifrn elsern return true;rnrnrn在这里我觉得api.sqlite3_exec(db,"BEGIN",NULL,NULL,&zErr);和api.sqlite3_exec(db,"COMMIT",NULL,NULL,&zErr);这两行代码没有起到什么作用?另外,不知道sqlite3_get_table没有返回结果的时候,那个pResult是不是为空的。rnrn我对这个函数进行了测试,在测试的时候,我在一个线程里每秒钟往数据库里添加数据,在另外一个线程里查询10秒钟内添加的表中的一项的平均值,具体的代码是这样的:rnrnint main()rnrn int res;rn pthread_t a_thread;rn// void *thread_result;rnrn char* sql = "create table time(time text, id int, id1 int, id2 int, id3 int, id4 int);";rnrn //创建表rn if(FALSE == SQL_Exec(database, sql))rn rn printf("lxx add*table cannot created\r\n"); //lxx addrn //return 0;rn rn EXACT_TIME e_time; //定义时间rnrn char sqlInsert[100];rnrn res = pthread_create(&a_thread, NULL, thread_function, NULL);rn if(res != 0)rn rn perror("Thread creation failed!");rn exit(EXIT_FAILURE);rn rnrn struct timeval tv_begin, tv_end; // lxx addrn while(1)rn rn// printf("lxx add***%s(%d)of%s*****\r\n",__FUNCTION__,__LINE__,__FILE__); //lxx addrn get_exact_time(&e_time);rnrn sprintf(sqlInsert, "insert into time values('%4d-%2d-%2d %2d:%2d:%2d:%6d', 100, 100, 1000, 10, 100);",rn e_time.year, e_time.month, e_time.day, e_time.hour, e_time.min, e_time.second,rn e_time.microsec);rnrn gettimeofday(&tv_begin, NULL); // lxx addrn if(FALSE == SQL_Exec(database, sqlInsert))rn rn printf("lxx addcannot insert\r\n"); //lxx addrn //return 0;rn //end ifrn gettimeofday(&tv_end, NULL);rn long runT = 1000000 * (tv_end.tv_sec - tv_begin.tv_sec) + tv_end.tv_usec - tv_begin.tv_usec;rn// printf( "lxx insert time = %ld\n", runT); // lxx addrn lxx_write_long("/sqlite/insert.txt", runT);rnrn sleep(1);rn //end whilernrn printf("Waiting for thread to finish...\n");rnrn// res = pthread_join(a_thread, &thread_result);rn// if(res != 0)rn// rn// perror("Thread join failed!\n");rn// exit(EXIT_FAILURE);rn// rnrn // printf("Thread joined, it returned %s\n", (char *)thread_result);rn // printf("Message is now %s\n", message);rnrn exit(EXIT_FAILURE);rnrnrnvoid *thread_function(void *arg)rnrn char sqlSelect[110];rn static EXACT_TIME e_start_time; //定义开始时间rn static EXACT_TIME e_end_time; //定义开始时间rn struct timeval begin, end; // lxx addrnrn while(1)rn rn// printf("lxx add***%s(%d)of%s*****\r\n",__FUNCTION__,__LINE__,__FILE__); //lxx addrn int nRow = 0;rn int nCol = 0;rn int i=0, j=0;rn char **pResult = NULL;rn get_exact_time(&e_start_time);rn sleep(10);rn get_exact_time(&e_end_time);rnrn sprintf(sqlSelect,"select AVG(id) from time where time between"rn "'%4d-%2d-%2d %2d:%2d:%2d:%6d' and '%4d-%2d-%2d %2d:%2d:%2d:%6d';",rn e_start_time.year, e_start_time.month, e_start_time.day,rn e_start_time.hour, e_start_time.min, e_start_time.second, e_start_time.microsec,rn e_end_time.year, e_end_time.month, e_end_time.day,rn e_end_time.hour, e_end_time.min, e_end_time.second, e_end_time.microsec);rnrn gettimeofday(&begin, NULL); // lxx addrn if(FALSE == SQL_Select(database, sqlSelect, &pResult, &nRow, &nCol))rn rn printf("lxx add*cannot select\r\n"); //lxx addrn //end ifrn gettimeofday(&end, NULL);rn long runT = 1000000 * (end.tv_sec - begin.tv_sec) + end.tv_usec - begin.tv_usec;rn printf( "lxx select = %ld\n", runT); // lxx addrn lxx_write_long("/sqlite/select.txt", runT);rnrn for(i = 0; i < nRow; i++)rn rn for(j = 0; j < nCol; j++)rn rn //the i+1 term skips over the first record which is the columnheadersrn printf("%s\n", pResult[(i+1)*nCol + j]);rn //end forrn //end forrn if(pResult != NULL)rn rn SQL_FreeMemory(pResult);rn pResult = NULL;rn rnrnrn //end whilern//printf("lxx add***%s(%d)of%s*****\r\n",__FUNCTION__,__LINE__,__FILE__); //lxx addrnrnrn在测试的时候发现输出的时间值会越来越长,而且会有一定的内存泄漏。rn想请高手帮我看下,这是怎么回事了,是sqlite本身的问题的问题还是我程序的问题呢?rnrn谢谢啦rn

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试