sqlite使用范围很广,这由其sql语言可扩展性决定的。这其中就包括了C,Perl,Python,Ruby,Java和一些其他的主流程序设计语言。我们这里只讨论C语言内对sqlite的使用细节。
我在以前使用Java些Android的时候,Android使用java封装了很多数据库操作的函数接口,比如delete,insert,replace等等,都有专门的接口。其实这些函数接口后台都被编译成了一条条的sql语句,你也可以直接使用sqlite3_exec(****)直接执行sql语句。既然如此,何必使用呆板的接口语句?这等于浪费广大程序员的时间去了解几个多余的封装函数,简直就是没有必要的。直接使用sql语句不更加方便明了?C也是如此,我们可以发现,C-API中并没有像Android中封装的那么厉害。
C/C++接口介绍:http://www.sqlite.org/c3ref/intro.html
其中函数部分链接:http://www.sqlite.org/c3ref/funclist.html
在里面你找不到像Android那样的删除,插入之类的命令。很多初学者就很纳闷,那我怎么删除和插入呢?别着急,我们先来寻找解决办法。
Compiling An sql Statement int sqlite3_prepare( sqlite3 *db,/* Database handle */ const char *zsql,/* sql statement,UTF-8 encoded */ int nByte,/* Maximum length of zsql in bytes. */ sqlite3_stmt **ppStmt,/* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zsql */ ); int sqlite3_prepare_v2( sqlite3 *db,/* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zsql */ ); int sqlite3_prepare16( sqlite3 *db,/* Database handle */ const void *zsql,UTF-16 encoded */ int nByte,/* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zsql */ ); int sqlite3_prepare16_v2( sqlite3 *db,/* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zsql */ );上面是我在官方网站找到的sqlite3_prepare家族所有的C函数申明,我比较常用的是sqlite3_prepare_v2,查询的过程可以是insert,update或者delete。这取决于sql字符串的定义是怎么样子的,你想怎么使用它而已。具体字段含义,只讲一个,sqlite3_stmt **ppStmt。一旦查询语句就绪,下一步就是使用sqlite3_step()执行。sqlITE_BUSY也是在这里被返回的。sqlite3_stmt 这个结构体,将字节代码(我们通常所说的需要绑定的数据)关联(绑定)到单个语句句柄。这种结构体比用来执行sql语句并获取相关记录的不透明句柄的内容更多。但是,这种数据结构包含了命令的字节码,绑定的参数,B-tree游标,执行上下文以及sqlite3_step()在执行过程中管理查询状态所需的其他数据。
我们可以使用如下任何一种C接口给其绑定数据:
Binding Values To Prepared Statements int sqlite3_bind_blob(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*,double); int sqlite3_bind_int(sqlite3_stmt*,int); int sqlite3_bind_int64(sqlite3_stmt*,sqlite3_int64); int sqlite3_bind_null(sqlite3_stmt*,int); int sqlite3_bind_text(sqlite3_stmt*,const char*,void(*)(void*)); int sqlite3_bind_text16(sqlite3_stmt*,void(*)(void*)); int sqlite3_bind_value(sqlite3_stmt*,const sqlite3_value*); int sqlite3_bind_zeroblob(sqlite3_stmt*,int n);具体都是绑定什么,希望大家自己去看看。
接下来就是可以调用sqlite3_step()去执行你所需要执行的删除,插入,更新,查询操作了。这就是我们称之为带参数的C语言sqlite操作。
下面是几个例子代码片段:
插入或替换
sql = "insert or replace into fpgaData(id,dev_num,state_flg,error_cd,present_p,power,year,month,day,min) values(?,?,?)"; if(sqlite3_prepare_v2(db,sql,-1,&stmt,NULL) == sqlITE_OK){ //bind data for insert new line,total 1 line sqlite3_bind_int(stmt,1,1); ...... sqlite3_step(stmt); sqlite3_finalize(stmt); }else{ sqlite3_finalize(stmt); return 1; }查询
sql= "select wh,day from totalPwy order by year,day ASC "; if(sqlite3_prepare_v2(db,NULL) == sqlITE_OK){ *count = 0; while(sqlite3_step(stmt) == sqlITE_ROW){ <span style="white-space:pre"> </span>(currentp->wh) = sqlite3_column_int(stmt,0); ...... } sqlite3_finalize(stmt); } else{ sqlite3_finalize(stmt); }
sql = "delete from fpgaData where dev_num=?"; if(sqlite3_prepare_v2(db,NULL) == sqlITE_OK){ sqlite3_bind_int(stmt,dev_num); while(sqlite3_step(stmt) == sqlITE_ROW); sqlite3_finalize(stmt); } else{ sqlite3_finalize(stmt); return 1; }更新
sql = "update fpgaData set state_flg=?,error_cd=?,present_p=?,power=?,year=?,month=?,day=?,min=? \ where id=? and dev_num=?"; int data_p; for(data_p = 1; data_p <= *dev_cnt; data_p++){ if(sqlite3_prepare_v2( db,NULL) == sqlITE_OK){ //bind data for updata new line,total 48 line sqlite3_bind_int(stmt,s_data[(data_p-1)*10 + 2]); //status flags ..... .... sqlite3_step(stmt); sqlite3_finalize(stmt); }else{ sqlite3_finalize(stmt); data_p--; } }
当然,也可以直接使用sqlite3_exec()执行sql语句。在实际应用中,你会发现每个查询函数都有其用途。sqlite3_exec()对于修改数据库的命令(创建,丢弃,插入,更新,删除)特别合适,我的理解是不带参数的操作,用它会加快速度,而且一点都不繁琐。反之,则使用sqlite3_prepare()进行编译,sqlite3_step()进行执行会比较好。最后,不要忘记使用sqlite3_finalize()释放stmt结构体,关闭查询,这个具体原因我没有深究,请各位自己探讨了,毕竟是写给新手看的。谅解。。。。
sqlite3_exec()和sqlite3_step()(执行查询)类似,但是提供的功能较少,可以自定义封装的余地小。而sqlite3_get_table()(获取表查询)返回的是单独一个sql命令中的整个结果集,他也可以连续运行多条sql命令,具体希望读者自行去sqlite官网查阅怎么使用。
OVER~~~~