整合网上的资料,便于以后自己查找。
1.使用的过程根据使用的函数大致分为如下几个过程
sqlite3_open()
sqlite3_prepare()
sqlite3_step()
sqlite3_column()
sqlite3_finalize()
sqlite3_close()
这几个过程是概念上的说法,而不完全是程序运行的过程,如sqlite3_column()表示的是对查询获得一行里面的数据的列的各个操作统称,实际上在sqlite中并不存在这个函数。
1、sqlite3_open
函数定义:
sqlITE_API int sqlITE_STDCALL sqlite3_open(
const char *filename,/* Database filename (UTF-8)*/
sqlite3 **ppDb /* OUT:sqlite db handle */
);
在操作数据库之前,首先要打开数据库。这个函数打开一个sqlite数据库文件,并且返回一个数据库连接对象。假如这个要被打开的数据文件不存在,则一个同名的数据库文件将被创建。
如果使用sqlite3_open和sqlite3_open_v2的话,数据库将采用UTF-8的编码方式,sqlite3_open16采用UTF-16的编码方式。如果sqlite数据库被成功打开(或创建),将会返回sqlITE_OK,否则将会返回错误码。
filename:需要被打开的数据库文件的文件名,在sqlite3_open和sqlite3_open_v2中这个参数采用UTF-8编码,而在sqlite3_open16中则采用UTF-16编码。
ppDb:一个数据库连接句柄被返回到这个参数,即使发生错误。唯一的异常是如果sqlite不能分配内存来存放sqlite对象,ppDb将会被返回一个NULL值。
2、sqlite3_prepare
函数定义:
sqlITE_API int sqlITE_STDCALL sqlite3_prepare(
sqlite3 *db,/* Database handle */
const char *zsql,/* sqlstatement,UTF-8 encoded */
int nByte,/* Maximum length of zsql in bytes. */
sqlite3_stmt **ppStmt,/* OUT: Statement handle */
const char **pzTail /* OUT: Pointer tounused portion of zsql */
);
这个函数将sql文本转换成一个准备语句(prepared statement)对象,同时返回语句对象的句柄。这个接口需要一个数据库连接指针以及一个要准备的包含sql语句的文本。它实际上并不执行(evaluate)这个sql语句,它仅仅为执行准备这个sql语句。
db:数据库连接指针。
zsql:sql语句,使用UTF-8编码。
nByte:如果nByte小于0,则函数取出zsql中从开始到第一个0终止符的内容;如果nByte不是负的,那么它就是这个函数能从zsql中读取的字节数的最大值。如果nBytes非负,zsql在第一次遇见‘/000/’或‘u000’的时候终止。
pzTail:上面提到zsql在遇见终止符或者是达到设定的nByte之后结束,假如zsql还有剩余的内容,那么这些剩余的内容被存放到pZTail中,不包括终止符。
ppStmt:能够使用sqlite3_step()执行的编译好的准备语句的指针,如果错误发生,它被置为NULL,如假如输入的文本不包括sql语句。调用过程必须负责在编译好的sql语句完成使用后使用sqlite3_finalize()删除它。
3、sqlite3_step
函数定义:
sqlITE_API int sqlITE_STDCALLsqlite3_step(sqlite3_stmt*);
这个过程用于执行有前面sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调用sqlite3_setp()。继续调用sqlite3_setp()直到这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只执行一次就返回。
4、sqlite3_column
函数定义:
sqlITE_API const void* sqlITE_STDCALLsqlite3_column_blob(sqlite3_stmt*,intiCol);
sqlITE_API int sqlITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*,intiCol);
sqlITE_API int sqlITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*,intiCol);
sqlITE_API double sqlITE_STDCALL sqlite3_column_double(sqlite3_stmt*,intiCol);
sqlITE_API int sqlITE_STDCALL sqlite3_column_int(sqlite3_stmt*,intiCol);
sqlITE_API sqlite3_int64 sqlITE_STDCALL sqlite3_column_int64(sqlite3_stmt*,intiCol);
sqlITE_API const unsigned char* sqlITE_STDCALLsqlite3_column_text(sqlite3_stmt*,intiCol);
sqlITE_API const void* sqlITE_STDCALLsqlite3_column_text16(sqlite3_stmt*,intiCol);
sqlITE_API int sqlITE_STDCALL sqlite3_column_type(sqlite3_stmt*,intiCol);
sqlITE_API sqlite3_value* sqlITE_STDCALLsqlite3_column_value(sqlite3_stmt*,intiCol);
这个过程从执行sqlite3_step()执行一个准备语句得到的结果集的当前行中返回一个列。每次sqlite3_step得到一个结果集的列停下后,这个过程就可以被多次调用去查询这个行的各列的值。对列操作是有多个函数,均以sqlite3_column为前缀。
第一个参数为从sqlite3_prepare返回来的prepared statement对象的指针。
第二参数指定这一行中的想要被返回的列的索引。最左边的一列的索引号是0,行的列数可以使用sqlite3_colum_count()获得。
5、sqlite3_finalize
函数定义:
sqlITE_API int sqlITE_STDCALLsqlite3_finalize(sqlite3_stmt *pStmt);
这个过程销毁前面被sqlite3_prepare创建的准备语句,每个准备语句都必须使用这个函数去销毁以防止内存泄露。
6、sqlite3_exec
函数定义:
sqlITE_API int sqlITE_STDCALL sqlite3_exec(
sqlite3*,/* An opendatabase */
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 */
);
sqlite3_step 和sqlite3_exec 都可以用于执行sql语句,他们的区别在于后者是sqlite3_prepare()、sqlite3_step()和 sqlite3_finalize() 的封装,能让程序多次执行sql语句而不要写许多重复的代码,然后提供一个回调函数进行结果的处理。
第1个参数:数据库连接指针。
第2个参数:是一条sql语句。
第3个参数:是一个函数指针,当这条语句执行之后,sqlite3会去调用你提供的这个函数。
第4个参数:是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写法,以及这个参数的使用。
第5个参数:是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行sqlite3_exec 之后,执行失败时可以查阅这个指针。
7、sqlite3_close
函数定义
sqlITE_API int sqlITE_STDCALL sqlite3_close(sqlite3*);
这个过程用于关闭数据库
2.Bind用法
参数绑定:
和大多数关系型数据库一样,sqlite的sql文本也支持变量绑定,以便减少sql语句被动态
解析的次数,从而提高数据查询和数据操作的效率。要完成该操作,我们需要使用sqlite提
供的另外两个接口APIs,sqlite3_reset和sqlite3_bind。
见如下示例:
//1. 不带参数绑定的情况下插入多条数据。
char strsql[128];
for (int i = 0; i < MAX_ROWS; ++i)
{
sprintf(strsql,"insert into testtable values(%d)",i);
sqlite3_prepare_v2(...,strsql);
sqlite3_step(prepared_stmt);
sqlite3_finalize(prepared_stmt);
}
//2. 参数绑定的情况下插入多条数据。
string strsqlWithParameter = "insert intotesttable values(?)";
sqlite3_prepare_v2(...,strsql);
for (int i = 0; i < MAX_ROWS; ++i)
{
sqlite3_bind(...,i);
sqlite3_step(prepared_stmt);
sqlite3_reset(prepared_stmt);
}
sqlite3_finalize(prepared_stmt);
这里首先需要说明的是,sql语句"insert into testtable values(?)"中的问号(?)表示参数变量的占位符,该规则在很多关系型数据库中都是一致的,因此这对于数据库移植操作还是比较方便的 。 通过上面的示例代码可以显而易见的看出,参数绑定写法的执行效率要高于每次生成不同的sql语句的写法,即2)在效率上要明显优于1),下面是针对这两种写法的具体比较: 1. 单单从程序表面来看,前者在for循环中执行了更多的任务,比如字符串的填充、sql语句的prepare,以及prepared_statement对象的释放。 2. 在sqlite的官方文档中明确的指出,sqlite3_prepare_v2的执行效率往往要低于sqlite3_step的效率。 3. 当插入的数据量较大时,后者带来的效率提升还是相当可观的。