最近在做一个C++的项目,里面用到了SQLIte数据库。于是,到官网去查看SQLite 的C++接口,因为到网上的博客去看别人写的SQLite教程,有些看不太懂,所以只好到官网上去看。其实,我还是喜欢用Qt来操作SQLite,因为Qt 对SQLite的接口函数进行了封装,操作更方便。但是项目组里的其他人用的是VS 2010,于是,不得不去看官网的英文文档。 SQLite C/C++ 接口网址:http://www.sqlite.org/cintro.html点击打开链接
下面对它们的用法进行说明:
2.0 打开数据库:
如:sqlite3 *mysqlite3; //定义一个数据库句柄,可以理解为一个数据库连接
sqlite3_open("D:\\mysqlite\\mysqlite.db",&mysqlite3);
该接口把一个SQL语句文本转换成一个预处理语句对象并返回一个指向该对象的指针。这个接口需要一个由先前调用sqlite3_open()返回的数据库连接对象指针以及一个预处理的SQL语句文本字符串为参数。这个API并不实际解析SQL语句,仅仅是为后续的解析而对SQL语句进行的预处理。也就是说,调用sqlite3_prepare()将SQL语句编译为sqlite内部一个结构体(sqlite3_stmt),该结构体中包含了将要执行的的SQL语句的信息。
如:sqlite3_prepare_v2(mysqlite3,"select * from friends",-1,&stmt,NULL);地调用sqlite3_step()直至整个语句完成为止。对于那些并不返回结果的语句(例如:insert,delete语句等)一次调用sqlite3_step()就完成了语句的处理。注意,调用sqlite3_step()这时候SQL语句才真正执行,一次它只返回一行数据。
返回值:SQLITE_BUSY:数据库被锁,可以等待释放后重新调用该函数
SQLITE_DONE:成功
SQLITE_ROW:成功并且有数据返回,每查询到一条数据都会返回该值
SQLITE_ERROR:失败
SQLITE_MISUSE:错误的调用,比如已经返回了SQLITE_DONE或者SQLITE_ERROR后还继续调用该函数
2.3 对返回的行数据中的每一列进行查询:sqlite3_column_xxx, 其中blob,double,int,int64,text,text16表示的是要查询的那一列的数据类型
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);//其中参数iCol为列号,从0开始,即第一列为0int sqlite3_finalize(sqlite3_stmt *pStmt);
sqlite3_finalize()释放之前调用sqlite3_prepare()创建的预处理语句stmt占用的内存,该内存是在sqlite3_prepare()时分配的,每一个预处理语句都必须调用这个接口进行销毁以避免内存泄漏。
如:sqlite3_finalize(stmt);如:sqlite3_close(mysqlite3);
void Talk() //根据ID号204,查询其IP为多少
{
sqlite3 *mysqlite3; //SQLite 连接对象
int reopen;
reopen = sqlite3_open("D:\\mysqlite\\mysqlite.db",&mysqlite3);//返回值如果是SQLITE_OK,则打开成功,SQLITE_OK为sqlite3.h中的宏定义
if(reopen != SQLITE_OK ) //#define SQLITE_OK 0 /* Successful result */ {
cout<<"it failed to open mysqlite.db"<
{
cout<<"it success to open mysqlite.db"<
sqlite3_stmt *stmt;//prepare_statment 对象
char *sql="select IP from userInfo where ID = 204"; //SQL语句,表示查询ID=204所在的那行的IP那一列的数据
sqlite3_prepare_v2(mysqlite3,sql,-1,&stmt,NULL); //把SQL语句作为第二个参数传入,第三个参数-1 表示自动按字符串计算sql语句长度,第五个一般为NULL
int restep = sqlite3_step(stmt)//返回值如果是SQLITE_ROW,表示成功并且有数据返回,SQLITE_ROW为sqlite3.h中的宏定义
if(restep == SQLITE_ROW) //#define SQLITE_ROW 100
{
char *IP= (char *)sqlite3_column_text(stmt,0); //因为这里只返回IP那一列的值,所以第二个参数为0 cout << IP<
sqlite3_finalize(stmt);
sqlite3_close(mysqlite3);
}
通过上面的例子相信大家应该基本学会了SQLITE3的基本用法,再来分析上面的例子,相信大家会发现它的不灵活,因为它查询的ID是写死的,如果我想查询任一个ID的信息呢?那就需要把ID作为形参传入这个函数,这就是接下来要讲的:
(二)参数绑定和重新执行已编译语句
在上面的讨论中,假定每个SQL语句一旦准备,然后就执行,最后被销毁。然而,SQLite3允许相同的预处理语句执行多次。这时使用以下程序来完成:sqlite3_bind() sqlite3_reset()
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); //sqlite3_bind_ 后面跟 着的大多是绑定的数据类型,有二进制对象,整形等
int sqlite3_bind_double(sqlite3_stmt*, int, double); //所有的这些函数第二个参数表示绑定SQL语句中的第几 个参数,最左边的SQL参数的索引为1
int sqlite3_bind_int(sqlite3_stmt*, int, int); //第三个参数为绑定到占位符的值,即SQL参数的值
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);//第四个参数为参数的字节数(注意不是字符数),如 果为负,则把参数当作字符串输入
int sqlite3_reset(sqlite3_stmt *pStmt); //第一个参数是一个指向sqlite3_stmt对象的指针
即sqlite3_bind_XXX()函数将对应的参数传入,sqlite3_reset()来清除已经绑定的参数。当一个准备语句(prepared statement)被执行通过一次或多次调用sqlite3_step ( ) ,它也可以调用sqlite3_reset ( )来重置。之所以调用sqlite3_reset()来重置而不是调用sqlite3_prepare()来重新创建,是因为可以避免不必要的消耗。通常我们很少多次执行完全相同的SQL语句,更多的时候我们可能需要执行一个相似的语句,比如插入多条数据,执行的是相似的INSERT语句,只是其中包含的参数不同,这些参数可以在语句被执行之前绑定到一个变量上,我们只需要不断的改变这个变量的值,然后执行相同的准备语句(prepared statement)即可。
sqlite3_reset()是来清除已经绑定的参数,比较简单,这里不多讲它的用法了。