Sqlite3数据库的初步学习
Sqlite3数据库的初步学习 最近由于项目的需要,初步学习了Sqlite3数据库技术。现共享,希望能与家共同学习。至于深入的学习我将在后继的博客中与大家深入交流。SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中应用非常广泛(关注我博客的朋友,就会发现,我的另一篇博客:基于Ubuntu-Woojoy的QT4版mini电话薄设计,其实就一个成功的小案例)。同样,大家亦可以参考其官网:http://www.sqlite.org。 需要说明的是,我使用的SQLite3中的API大约包括80个函数。只有8个函数在连接、查询和断开连接时必须的,其它的函数用来完成特定的任务。下我就从基础的函数使用讲起。 一、创建表 CREATE[TEMP|TEMPORARY]TABLE 例如: char*sql="CREATETABLESensorData(/ IDINTEGERPRIMARYKEY,/ SensorIDINTEGER,/ SiteNumINTEGER,/ TimeVARCHAR(12),/ SensorParameterREAL);"; 参数[TEMP|TEMPORARY]是用来建立临时表用的。大家可以参考相关资料,如需要帮助,也可以在我博客中留言。 SQLite具有以下五种数据类型:
NULL:空值;INTEGER:带符号的整型,具体取决有存入数字的范围大小;REAL:浮点数字,存储为8-byteIEEE浮点数;TEXT:字符串文本;BLOB:二进制对象。
二、改变表 ALTERTABLEtable{RENAMETOname|ADDCOLUMNcolumn_def}
RENAMETOname对表重命名; ADDCOLUMNcolumn_def增加表行信息; 执行ALTERTABLESensorData ADDCOLUMNemailTEXTNOTNULLDEFAULT"COLLATENOCASE;完有: char*sql="CREATETABLESensorData(/ IDINTEGERPRIMARYKEY,/ SensorParameterREAL/ emailTEXTNOTNULLDEFAULT"COLLATENOCASE;);"; 三、关系操作
SELECT语法
SELECT语法说明 由于SELECT语句是比较复杂的语句,在此就不细说了。当然,我会在下面的实例中具体用到。 四、打开数据库,关闭数据库 Intsqlite3_open(文件名,sqlite3**); Intsqlite3_close(sqlite3**); 五、执行语句 (I)Intsqlite3_exec(sqlite3*,contchar*sal,sqkite3_callback,void*,char**errmsg): 这就是一条sql语句的函数。 第1个参数不再说了,是前面open函数得到的指针。 第2个参数constchar*sql是一条sql语句,以/0结尾。 第3个参数sqlite3_callback是回调函数,当这条语句执行之后,sqlite3会去调用你提供的这个函数(什么是回调函数,下面我会给出一个例子,助大家来理解)。 第4个参数void*是你所提供的指针,你可以传递任何一个指针到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,我们可以填NULL。 第5个参数char**errmsg是错误信息。注意是指针的指针。Sqlite3里面有很多回定的错误信息,执行sqlite3_exec之后,执行失败时可以查阅这个指针(直接printf("%s/n",errmsg))得到一串字符串信息,这串信息告诉你错在什么地方。 注意:通常,sqlte3_callback和它后面的void*这两个位置都可以真NULL。NULL表示你不需要回调。比如你做insert操作,做delete操作,就没有必要使用回调。而当你做select时,就要使用回调,因为sqlite3把数据查出来,得通过回调告诉你查出了什么数据。 (II)回调函数 Typedefint(*sqlite3_callback)(voic*,int,char**,char**); 下面是回调函数一个实例,现与大家共享: #include<stdio.h> #include<stdlib.h> #include"sqlite3.h" intcallback(void*data,intncols,char**values,char**headers) { inti; fprintf(stderr,"%s:",(constchar*)data); for(i=0;i<ncols;i++) { fprintf(stderr,"%s=%s",headers[i],values[i]); fprintf(stderr,"/n"); } return0; } intmain(intargc,char**argv) { sqlite3*db; intrc; char*sql; char*zErr; char*data; rc=sqlite3_open("test.db",&db); if(rc) { fprintf(stderr,"Can'topendatabase:%s/n",sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } sql="CREATETABLEta(/ IDINTEGERPRIMARYKEY,/ nameVARCHAR(32));"; rc=sqlite3_exec(db,sql,NULL,&zErr); if(rc!=SQLITE_OK) { if(zErr!=NULL) { //fprintf(stderr,"SQLerror:%s/n",zErr); sqlite3_free(zErr); } } data="Callbackfunctioncalled/n"; sql="insertinto/"ta/"values(NULL,'888');"; sqlite3_exec(db,&zErr); sql="select*Fromta;"; rc=sqlite3_exec(db,callback,data,&zErr); if(rc!=SQLITE_OK) { if(zErr!=NULL) { fprintf(stderr,zErr); sqlite3_free(zErr); } } sqlite3_close(db); return0; } 以下是Ubuntu-Woojoy下运行的结果:
虽然回调显得代码整齐,但有时,你还是可想要非回调的select查询。这可以通过下面的函数做到。 (III)intsqlite3_get_table(sqlite3*,constchar*sql,char**resultp,int*nrow,int*ncolumn,char**errmsg); 第1个参数,同上。 第2个参数是sql语句,跟sqlite3_exec里的sql是一样的。 第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。 第4个参数是查询出多少条记录(即查出多少行)。 第5个参数是多个字段(多少列)。 第6个参数是错误信息,跟前面一样。 六、修改数据 Sqlite3主要有2个DML语句用于修改数据------INSERT,UPDATE,DELETE。 INSERTINTOtable(column_list)VALUES(value_list); UPDATEtableSETupdate_listWHEREpredicate; DELETEFROMfoodsWHEREname=''; 七、下面我们就上面的知识来一个实用例子(在Ubuntu-Woojoy运行通过) #include<stdio.h> #include<stdlib.h> #include"sqlite3.h" //#define_DEBUG_ intmain() { sqlite3*db=NULL; char*zErrMsg=0; intrc; rc=sqlite3_open("zieckey.db",&db); if(rc) { fprintf(stderr,"can'topendatabase:%s/n",sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } else printf("opendatabase/n"); char*sql="CREATETABLESensorData(/ IDINTEGERPRIMARYKEY,/ SensorIDINTEGER,/ SiteNumINTEGER,/ TimeVARCHAR(12),/ SensorParameterREAL);"; // printf("OK,%d/n",__LINE__); sqlite3_exec(db,&zErrMsg); // printf("OK,__LINE__); #ifdef_DEBUG_ printf("%s/n",zErrMsg); #endif // printf("OK,__LINE__); /*<----------------------------insert------------------------------------------->*/ sql="INSERTINTO/"SensorData/"VALUES(NULL,1,'200605011206',18.9);"; rc=sqlite3_exec(db,&zErrMsg);//执行不需要返回数据的查询 if(rc!=SQLITE_OK) { printf("failedexec!,err_code:%d,err_reason:%s/n",rc,zErrMsg); } // printf("OK,__LINE__); sql="INSERTINTO/"SensorData/"VALUES(NULL,'200605011306',16.9);"; sqlite3_exec(db,&zErrMsg); /*if(rc!=QLITE_OK){ if(zERR!=NULL){ fprintf(stderr,zErr); sqlite_free(zErr); } }*/ // printf("OK,__LINE__); /*<-----------------------------query--------------------------------------->*/ intnrow=0; intncolumn=0; char**azResult; sql="SELECT*FROMSensorData;"; //返回一个表格化的结果集 sqlite3_get_table(db,&azResult,&nrow,&ncolumn,&zErrMsg); inti=0; printf("row:%d,column:%d/n",nrow,ncolumn); printf("thequeriedresultis:/n"); for(i=0;i<(nrow+1)*ncolumn;i++) printf("azResult[%d]:%s/n",i,azResult[i]); /*<-----------------------------delete--------------------------------------->*/ sql="DELETEFROMSensorDataWHEREID=1;"; sqlite3_exec(db,&zErrMsg); #ifdef_DEBUG_ printf("zErrMsg=%s/n",zErrMsg); #endif sql="SELECT*FROMSensorData;"; sqlite3_get_table(db,&zErrMsg); printf("/n/n/n/nrow:%dcolumn=%d",ncolumn); printf("/nAfterdeleting,theresultofqueryingis:/n"); for(i=0;i<(nrow+1)*ncolumn;i++) printf("azResult[%d]=%s/n",azResult[i]); sqlite3_free_table(azResult); #ifdef_DEBUG_ printf("%s/n",zErrMsg); #endif /*<-----------------------------update--------------------------------------->*/ sql="UPDATESensorDataSETID='1'WHEREID='2';"; puts(sql); sqlite3_exec(db,&zErrMsg); #ifdef_DEBUG_ printf("/nzErrMsg=%s/n",ncolumn); printf("/nAfterupdate,zErrMsg); #endif sqlite3_close(db); return0; }
八、下面与大家共享一个自创函数(在Ubuntu-Woojoy运行通过) 关于自创函数的概念。大可以查阅相关资料。时于时间的关系,我就不详述了,如需要帮助,可以在我博客上留言。 #include<stdio.h> #include<stdlib.h> #include"sqlite3.h" #include<string.h> voidfunction(sqlite3_context*ctx,intnargs,sqlite3_value**values) { inti; constchar*msg; fprintf(stdout,"function():Calledwith%iarguments/n",nargs); for(i=0;i<nargs;i++) { fprintf(stdout,"arg%i:value=%-7stype=%i/n", sqlite3_value_text(values[i]), sqlite3_value_type(values[i])); } if(strcmp((constchar*)sqlite3_value_text(values[0]),"fail")==0) { msg="function():Failingbecauseyoutoldmeto."; sqlite3_result_error(ctx,msg,strlen(msg)); fprintf(stdout,"/n"); return; } fprintf(stdout,"/n"); sqlite3_result_int(ctx,0); } intexecute(sqlite3*db,...) { char*err,*tmp; va_listap; va_start(ap,sql); //sql=sqlite3_mprintf("INSERTINTO/"TelephoneData/"VALUES(NULL,'%s','%s');",c_str1,c_str2,c_str3,c_str4,c_str5,c_str6); tmp=sqlite3_vmprintf(sql,ap); va_end(ap); intrc=sqlite3_exec(db,tmp,&err); if(rc!=SQLITE_OK) { if(err!=NULL) { fprintf(stdout,"execute():Error%i:%s/n",err); sqlite3_free(err); } } sqlite3_free(tmp); returnrc; } intmain(intargc,char**argv) { intrc; sqlite3*db; constchar*sql; sqlite3_open("test.db",&db); sqlite3_create_function(db,"function",-1,SQLITE_UTF8,function,NULL); //dbconnectiondata,-1ismaybehaveservelvarious //0isnohaveavarious /*TurnonSQLlogging*/ //log_sql(db,1); /*Callfunctionwithonetextargument.*/ execute(db,"selectfunction(1)"); /*Callfunctionwithseveralargumentsofvarioustypes.*/ execute(db,"selectfunction(1,2.71828)"); /*Callfunctionwithvariableargument'svalue **being'fail'.Thiswilltriggerthefunctiontocall **sqlite3_result_error().*/ execute(db,"selectfunction('fail',2.717828,'three',X'0004',NULL)"); /*Done*/ sqlite3_close(db); return0; }
九、结束语 首先非常感激您能阅完本文章。本篇由本人个人创作,当然欢迎您进行批评指正。 你也可以进行转载,但需标明出处,谢谢合作!! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |