转载

SQLITE使用(三)&&核心API使用

概述

SQLite提供了一系列接口供用户访问数据库,主要包括连接数据库,处理SQL,迭代查询结果等。本文会针对我们使用SQLite的主要场景,列出核心的API,详细介绍API的用法并给出代码用例。

1.打开关闭数据库

sqlite3_open_v2

原型:

 int sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ); 

作用:打开一个数据库连接

关键的参数:flags

SQLITE_OPEN_NOMUTEX: 设置数据库连接运行在多线程模式(没有指定单线程模式的情况下)

SQLITE_OPEN_FULLMUTEX:设置数据库连接运行在串行模式。

SQLITE_OPEN_SHAREDCACHE:设置运行在共享缓存模式。

SQLITE_OPEN_PRIVATECACHE:设置运行在非共享缓存模式。

SQLITE_OPEN_READWRITE:指定数据库连接可以读写。

SQLITE_OPEN_CREATE:如果数据库不存在,则创建。

sqlite3_close_v2

原型:

 int sqlite3_close_v2(sqlite3*); 

作用:关闭数据库连接,若关闭时连接上有未提交的事务,该事务会自动回滚。

1.1 例子 :打开关闭数据库连接

 sqlite3* pDb; char* filename="/u01/sqlite/test.db"; sqlite3_open_v2(filename, &pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL); .... .... sqlite3_close_v2(pDb); 

打开数据库文件test.db,对应的数据库连接可读可写,以多线程模式运行,并且运行在共享缓存模式,执行完操作后,关闭数据库连接。

2.更新SQL

更新SQL主要包括创建表,插入,删除,更新记录等,SQLite中常用的更新API有两个,一个是sqlite3_exec,另外一个是sqlite3_prepare_v2。

2.1 sqlite3_exec

原型:

 int sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ void *, /* 1st argument to callback */ char **errmsg /* Error msg written here */ ); 

其中参数sql可以包含多个SQL命令,语句之间以分号隔开,sqlite3_exec()将解析和执行sql字符串中的每个命令,直到到达该字符串的末尾或遇到错误。对于运行修改数据库的命令(创建,插入,删除,更新)非常适合,一个函数调用就可以完成全部操作。需要注意的是,虽然sqlite3_exec()可以执行多个SQL命令,但是函数不保证事务,即已执行成功的语句,不会因为后面执行失败的语句而回滚。

2.2 sqlite3_perpare_v2

原型:

 int sqlite3_prepare_v2( 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 */ ); 

sqlite3_exec实际上是将编译,执行进行了封装,与之等价的一组函数是 sqlite3_prepare_v2(), sqlite3_step()和sqlite3_finalize()。sqlite3_prepare_v2()编译SQL语句生成VDBE执行码,sqlite3_step()执行,sqlite3_finalize()关闭语句句柄,释放资源。两种方式,都可以通过调用sqlite3_changes(pdb),得到语句影响的行数。

2.3两种方式比较

(1).sqlite3_exec方式接口使用很简单,实现同样的功能,比sqlite3_perpare_v2接口代码量少。

(2).sqlite3_prepare方式更高效,因为只需要编译一次,就可以重复执行N次。

(3).sqlite3_prepare方式支持参数化SQL。

鉴于两种方式的差异,对于简单的PRAGMA设置语句(PRAGMA cache_size=2000),事务设置语句(BEGIN TRANSACTION,COMMIT,ROLLBACK)使用sqlite3_exec方式,更简单;而对于批量的更新、查询语句,则使用sqlite3_prepare方式,更高效。

2.4 例子 :prepare方式执行多sql的例子,pNext初始化在sql语句首部,执行完一个sql后,移动到下一个sql首部。

 const char *pNext = (const char *)sql; while (pNext && strlen(pNext) > 0) {   rc = sqlite3_prepare_v2(pDb, pNext, -1, &pStmt, &pNext);   if(SQLITE_OK != rc){     错误处理     break;   }         rc = sqlite3_step(pStmt);     if(SQLITE_OK != rc && SQLITE_DONE != rc){        错误处理        break;     }      rc = SQLITE_OK;      /*统计影响记录数目*/     resultCount += sqlite3_changes(pDb);      /* 清理语句句柄,准备执行下一个语句*/     sqlite3_finalize(pStmt); } 

3.查询SQL

3.1 sqlite3_get_table

原型:

 int sqlite3_get_table( sqlite3 *db, /* An open database */ const char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ int *pnRow, /* Number of result rows written here */ int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ ); 

该函数接收SQL语句返回的所有记录,使用sqlite内部分配的内存,将其存储在参数resultp中,必须使用sqlite3_free_table()释放内存。由于结果集可能非常大,会导致内存撑爆,因此对于大结果集的查询,不建议采用这种方式。

3.2 sqlite3_prepare_v2

prepare方式同样支持查询语句,主要分为3个阶段,编译,执行和结果集处理。前面更新SQL部分已经描述了prepare的基本步骤,这里主要讲结果集处理部分。首先通过sqlite3_column_count()可以得到结果集的列数目,通过sqlite3_column_type()可以得到具体某列的存储类型,方便我们调用合适的sqlite3_column_xxx接口处理字段值。主要有以下几类:

sqlite3_column_int

sqlite3_column_int64

sqlite3_column_double

sqlite3_column_text

sqlite3_column_blob

3.3 例子 :遍历结果集

 int rc = sqlite3_prepare_v2(pDb, sql, -1, &pStmt, NULL); //获取列数目 int n_columns = sqlite3_column_count(pStmt); do{   ret = sqlite3_step(stmt);   if (ret == SQLITE_ROW)    {     //处理每一列     for (i = 0; i < n_columns; i++)     {           /*获取列存储类型*/       type = sqlite3_column_type(stmt,i);       switch(type)       {         case SQLITE_INTEGER:          /*处理整型*/         sqlite3_column_int(stmt,i);         break;         case SQLITE_FLOAT:         /*处理浮点数*/         sqlite3_column_double(stmt,i);         break;         case SQLITE_TEXT:         /*处理字符串*/         sqlite3_column_text(stmt,i);               break;         case SQLITE_BLOB:         /*处理二进制*/         sqlite3_column_blob(stmt, i));          break;         case SQLITE_NULL:         /*处理空*/       }     }   }   else if (ret == SQLITE_DONE) //结束   {      break;   } }while(true); 

4.参数绑定

SQLite通过prepare接口可以支持参数化的SQL语句,即带问号的SQL语句。比如查询语句select * from t where id=?,或者插入语句 insert into t(a,b,c) values(?,?,?)。通过参数化SQL,可以实现一次编译多次执行的目的,由于问号是没有意义的,因此需要调用sqlite3_bind_xxx接口来绑定具体的参数。主要有以下几类:

sqlite3_bind_int

sqlite3_bind_int64

sqlite3_bind_double

sqlite3_bind_text

sqlite3_bind_blob

sqlite3_bind_null

关于绑定参数这里提一点,对于sqlite3_bind_text和sqlite3_bind_blob接口,绑定参数占据的存储空间是否可以被SQLite重用。接口中通过最后一个参数指定,参数值可以为SQLITE_STATIC和SQLITE_TRANSIENT。

SQLITE_STATIC :通知bind函数,参数使用空间是常量,不会改变,sqlite内部无需拷贝副本。

SQLITE_TRANSIENT :通知bind函数,参数使用空间可能会改变,sqlite内部需要有自己的副本。

4.1 例子 :批量导入

 //begin a transaction if(sqlite3_exec(pdb, "begin", NULL, NULL, &errmsg) != SQLITE_OK) {   错误处理   return ERROR; }  sqlite3_prepare_v2(pdb, "insert into t1 values(?,?,?);", &stmt); for (i = 0; i < n_rows; i++) {   for (j = 0; j < n_columns; j++)   {     switch(type)     {       case SQLITE_INTEGER:       /*处理整型*/       sqlite3_bind_int()       break;       case SQLITE_FLOAT:       /*处理浮点型*/       sqlite3_bind_double()       break;       case SQLITE_TEXT:       /*处理字符串类型*/       sqlite3_bind_text()       break;       case SQLITE_BLOB:       /*处理二进制类型*/       sqlite3_bind_blob       break;       case SQLITE_NULL:       sqlite3_bind_null(stmt, index);        break;        }       }    sqlite3_step(stmt);  //执行   sqlite3_reset(stmt); //将已编译的SQL语句恢复到初始状态,保留语句相关的资源 }  sqlite3_finalize(stmt); //结束语句,释放语句句柄  if(sqlite3_exec(pdb, "commit", NULL, NULL, &errmsg) != SQLITE_OK) {   错误处理      return ERROR;  } 

小结

本文详细描述了SQLite中实现创建,修改,查询数据库的接口使用,包括单SQL语句,多SQL语句和参数化SQL。主要从四个场景展开描述,打开关闭数据库连接,更新语句,查询语句和参数化语句,并且对于每一种使用场景,给出了相应的代码示范,希望能对大家熟悉使用SQLite有所帮助。

原文  http://www.cnblogs.com/cchust/p/5121559.html
正文到此结束
Loading...