sqlITE_API int sqlite3_open( const char *filename,/* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: sqlite db handle */ ); sqlITE_API int sqlite3_open16( const void *filename,/* Database filename (UTF-16) */ sqlite3 **ppDb /* OUT: sqlite db handle */ ); sqlITE_API 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 */ );
3个接口都可以用于 创建或 打开数据库。返回值给ppDb参数,如果内存申请失败,则ppDb为NULL。
sqlite3_open是一个基本接口。使用UTF-8编码。
sqlite_open16主要区别是使用UTF-16编码。
sqlite_open_v2使用UTF-8编码,sqlite_open_v2加入了两个新参数。
注意:Windows用户必须用UTF-8
编译sql语句
在执行sql语句之前,首先要编译成字节码。就像是在做准备(prepare)。另外还有两个UTF-16的没有列出来
sqlITE_API 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 */ ); sqlITE_API int sqlite3_prepare_v2( sqlite3 *db,/* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zsql */ );
要计算好sql语句的长度,注意单双字节。如果长度为空,则ppStmt为NULL。
返回值保存在ppStmt中做为下一步的参数。pzTail参数暂时没什么用。
两个接口的参数没有什么区别。在新程序中要使用v2,老的接口只是为了兼容。
注意:如果有并发操作会返回sqlITE_BUSY。
执行sql语句
编译成功后,就可以执行了。只有一个接口。
sqlITE_API int sqlite3_step(sqlite3_stmt*);
入参是上一步得到的ppStmt。
返回值可能是
- sqlITE_BUSY,被其他线程或进程锁住了。如果sql语句是一个事务中的COMMIT,可以重试,如果不是事务中的COMMIT,则需要回滚。
- sqlITE_DONE,执行完成。比如查询多行时已经到最后一行。
- sqlITE_ROW,意思是还有新行。
- sqlITE_ERROR,执行出错,只能是主键冲突,这时候就不要重试了。
- sqlITE_MISUSE,非法调用,可能是因为此ppStmt已经被sqlite3_finalize()回收了。
解析查询结果
sqlITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
sqlITE_API const char *sqlite3_column_name(sqlite3_stmt*,int N);
sqlITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*,int iCol);
分别获取列的数目,获取列名,获取值。
注意:只有第一次sqlite_step才返回列名(因为列名存在第一行),其余的行都返回结果。
回收ppStmt
在执行完查询以后,需要回收ppStmt。以免内存泄漏。
sqlITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
一步到位的执行接口
sqlITE_API 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 */ );
sqlite3_exec封装了从sqlite3_prepare,sqlite3_step到sqlite3_finalize等步骤的接口。
如果callback参数不为空,则执行完成后调用此回调函数。但这就导致程序变成了异步。所以笔者只用了写入,而不用来查询。
sqlite3_exec可以一次性执行多个sql语句,但如果第一句出错,其余的都会跳过。
errmsg可以用于接收错误信息(如果有的话),用完一定要sqlite3_free()掉,否则会内存泄漏。
sqlITE_API int sqlite3_close(sqlite3*); sqlITE_API int sqlite3_close_v2(sqlite3*);
注意:
如果ppStmt没有被finalize的话,执行sqlite3_close关闭数据库会报sqlITE_BUSY。
执行sqlite3_close_v2适合有垃圾回收的语言调用,因为析构函数的执行是随机的。
如果关闭后事务还正执行,则事务会回滚。
应该妥善处理每次执行接口的返回值。
如果返回值不是sqlITE_OK或查询时的sqlITE_DONE,可以用sqlite_errmsg()获取详细的错误信息。