SQLiteAPI接口学习总结.doc

上传人:wux****ua 文档编号:9658552 上传时间:2020-04-07 格式:DOC 页数:8 大小:41.50KB
返回 下载 相关 举报
SQLiteAPI接口学习总结.doc_第1页
第1页 / 共8页
SQLiteAPI接口学习总结.doc_第2页
第2页 / 共8页
SQLiteAPI接口学习总结.doc_第3页
第3页 / 共8页
点击查看更多>>
资源描述
库初始化int sqlite3_initialize(void); int sqlite3_shutdown(void); 在使用SQlite Library之前,首先应该调用sqlite3_initialize函数,该函数将分配资源,初始化一些必要的数据结构。与之配合使用的另一个函数是sqlite3_shutdown,该函数用来释放由sqlite3_initialize分配的资源。不过在很多客户的应用程序中通常直接调用sqlite3_open或者另一些主要的API函数,这些函数会自动初始化SQlite library(如果它还没有被初始化的话)。不过还是推荐客户应用程序显示调用这两个APIs函数来完成SQlite library的初始化和最后的清理工作。打开数据库int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 *ppDb /* OUT: SQLite db handle */ ); int sqlite3_open16( const void *filename, /* Database filename (UTF-16) */ sqlite3 *ppDb /* OUT: SQLite db handle */ ); 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 */ ); 在执行任何SQL语句之前,必须首先连接到一个数据库,也就是打开或者新建一个SQlite3数据库文件。连接数据库由sqlite3_open函数完成,它一共有上面3个版本。其中 sqlite3_open函数假定SQlite3数据库文件名为UTF-8编码,sqlite3_open_v2是它的加强版。sqlite3_open16函数假定SQlite3数据库文件名为UTF-16(Unicode宽字符)编码。 所有这三个函数,参数filename是要连接的SQlite3数据库文件名字符串。参数ppDb看起来有点复杂,它是一个指向指针的指针。当调用sqlite3_open_xxx函数时,该函数将分配一个新的SQlite3数据结构,然后初始化,然后将指针ppDb指向它。所以客户应用程序可以通过sqlite3_open_xxx函数连接到名为filename的数据库,并通过参数ppDb返回指向该数据库数据结构的指针。 示例代码:sqlite3 *pDB = NULL; Status rc = sqlite3_open(database.sqlite3, &pDB); 对于sqlite3_open和sqlite3_open16函数,如果可能将以可读可写的方式打开数据库,否则以只读的方式打开数据库。如果要打开的数据库文件不存在,就新建一个。对于sqlite3_open_v2函数,情况就要复杂一些了,因为这个v2版本的函数强大就强大在它可以对打开(连接)数据库的方式进行控制,具体是通过它的参数flags来完成。sqlite3_open_v2函数只支持UTF-8编码的SQlite3数据库文件。 如flags设置为SQLITE_OPEN_READONLY,则SQlite3数据库文件以只读的方式打开,如果该数据库文件不存在,则sqlite3_open_v2函数执行失败,返回一个error。如果flags设置为SQLITE_OPEN_READWRITE,则SQlite3数据库文件以可读可写的方式打开,如果该数据库文件本身被操作系统设置为写保护状态,则以只读的方式打开。如果该数据库文件不存在,则sqlite3_open_v2函数执行失败,返回一个error。如果flags设置为SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,则SQlite3数据库文件以可读可写的方式打开,如果该数据库文件不存在则新建一个。这也是sqlite3_open和sqlite3_open16函数的默认行为。除此之外,flags还可以设置为其他标志,具体可以查看SQlite官方文档。 参数zVfs允许客户应用程序命名一个虚拟文件系统(Virtual File System)模块,用来与数据库连接。VFS作为SQlite library和底层存储系统(如某个文件系统)之间的一个抽象层,通常客户应用程序可以简单的给该参数传递一个NULL指针,以使用默认的VFS模块。 对于UTF-8编码的SQlite3数据库文件,推荐使用sqlite3_open_v2函数进行连接,它可以对数据库文件的打开和处理操作进行更多的控制。 SQlite3数据库文件的扩展名没有一个标准定义,比较流行的选择是.sqlite3、.db、.db3。不过在Windows系统平台上,不推荐使用.sdb作为 SQlite3数据库文件的扩展名,据说这会导致IO速度显著减慢,因为.sdb扩展名有其特殊用义。关闭数据库int sqlite3_close(sqlite3 *); 在使用完SQlite数据库之后,需要调用sqlite3_close函数关闭数据库连接,释放数据结构所关联的内存,删除所有的临时数据项。如果在调用sqlite3_close函数关闭数据库之前,还有某些没有完成的(nonfinalized)SQL语句,那么sqlite3_close函数将会返回SQLITE_BUSY错误。客户程序员需要finalize所有的预处理语句(prepared statement)之后再次调用sqlite3_close。示例代码#include sqlite3.h #include int main( int argc, char *argv ) Char *file = database.sqlite3; sqlite3 *pDB = NULL; int rc = 0; sqlite3_initialize( ); rc = sqlite3_open_v2( file, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL ); if ( rc != SQLITE_OK) sqlite3_close( db ); exit( -1 ); /* perform database operations */ sqlite3_close( db ); sqlite3_shutdown( ) SQlite3数据库连接完成之后,就可以执行SQL命令了。下面将要介绍的prepare和step函数都是用来操作和执行SQL命令的。 典型的函数操作流程(伪代码):/* create a statement from an SQL string */ sqlite3_stmt *stmt = NULL; sqlite3_prepare_v2( db, sql_str, sql_str_len, &stmt, NULL ); /* use the statement as many times as required */ while( . ) /* bind any parameter values */ sqlite3_bind_xxx( stmt, param_idx, param_value. ); . /* execute statement and step over each row of the result set */ while ( sqlite3_step( stmt ) = SQLITE_ROW ) /* extract column values from the current result row */ col_val = sqlite3_column_xxx( stmt, col_index ); . /* reset the statement so it may be used again */ sqlite3_reset( stmt ); sqlite3_clear_bindings( stmt ); /* optional */ /* destroy and release the statement */ sqlite3_finalize( stmt ); stmt = NULL; 这段程序首先调用sqlite3_prepare_v2函数,将一个SQL命令字符串转换成一条prepared语句,存储在sqlite3_stmt类型结构体中。随后调用sqlite3_bind_xxx函数给这条prepared语句绑定参数。然后不停的调用sqlite3_step函数执行这条prepared语句,获取结果集中的每一行数据,从每一行数据中调用qlite3_column_xxx函数获取有用的列数据,直到结果集中所有的行都被处理完毕。 prepared语句可以被重置(调用sqlite3_reset函数),然后可以重新绑定参数之后重新执行。sqlite3_prepare_v2函数代价昂贵,所以通常尽可能的重用prepared语句。最后,这条prepared语句确实不在使用时,调用sqlite3_finalize函数释放所有的内部资源和sqlite3_stmt数据结构,有效删除prepared语句。预处理(Prepare)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, /* 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_prepare16( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt *ppStmt, /* OUT: Statement handle */ const void *pzTail /* OUT: Pointer to unused portion of zSql */ ); int sqlite3_prepare16_v2( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt *ppStmt, /* OUT: Statement handle */ const void *pzTail /* OUT: Pointer to unused portion of zSql */ ); 这些函数的作用是将SQL命令字符串转换为prepared语句。参数db是由sqlite3_open函数返回的指向数据库连接的指针。参数zSql是UTF-8或者UTF-16编码的SQL命令字符串,参数nByte是zSql的字节长度。如果nByte为负值,则prepare函数会自动计算出zSql的字节长度,不过要确保zSql传入的是以NULL结尾的字符串。如果SQL命令字符串中只包含一条SQL语句,那么它没有必要以“;”结尾。参数ppStmt是一个指向指针的指针,用来传回一个指向新建的sqlite3_stmt结构体的指针,sqlite3_stmt结构体里面保存有转换好的SQL语句。如果SQL命令字符串包含多条SQL语句,同时参数pzTail不为NULL,那么它将指向SQL命令字符串中的下一条SQL语句。上面4个函数中的v2版本是加强版,与原始版函数参数相同,不同的是函数内部对于sqlite3_stmt结构体的表现上。细节不去理会,尽量使用v2版本。 在sqlite3_prepare函数转换一条语句完毕之后,可以给这条语句绑定参数。语句参数允许我们插入一个特殊的占位符,然后给这个参数占位符绑定指定的值,然后再执行它。执行完成之后,还可以重置语句,绑定新的参数值,再重新执行该语句。像INSERT操作,每次执行INSERT命令,绑定不同的值,插入不同的数据。参数绑定是一个有点复杂的深入话题,在下一节中学习。步进(Step) int sqlite3_step(sqlite3_stmt*); sqlite3_prepare函数将SQL命令字符串解析并转换为一系列的命令字节码,这些字节码最终被传送到SQlite3的虚拟数据库引擎(VDBE: Virtual Database Engine)中执行,完成这项工作的是sqlite3_step函数。比如一个SELECT查询操作,sqlite3_step函数的每次调用都会返回结果集中的其中一行,直到再没有有效数据行了。每次调用sqlite3_step函数如果返回SQLITE_ROW,代表获得了有效数据行,可以通过sqlite3_column函数提取某列的值。如果调用sqlite3_step函数返回SQLITE_DONE,则代表prepared语句已经执行到终点了,没有有效数据了。很多命令第一次调用sqlite3_step函数就会返回SQLITE_DONE,因为这些SQL命令不会返回数据。对于INSERT,UPDATE,DELETE命令,会返回它们所修改的行号一个单行单列的值。结果列(Result Columns)int sqlite3_column_count(sqlite3_stmt *pStmt); 返回结果集的列数。const char *sqlite3_column_name(sqlite3_stmt*, int N); const void *sqlite3_column_name16(sqlite3_stmt*, int N); 返回结果集中指定列的列名,列的序号以0开始。比如一条SQL语句:SELECT pid AS person_id.,那么调用sqlite3_column_name函数返回结果集中第0列的列名就是person_id。返回的字符串指针将一直有效,直到再次调用sqlite3_column_name函数并再次读取该列的列名时失效。int sqlite3_column_type(sqlite3_stmt*, int iCol); 该函数返回结果集中指定列的本地存储类型,如SQLITE_INTEGER,SQLITE_FLOAT,SQLITE_TEXT,SQLITE_BLOB,SQLITE_NULL。为了获取正确的类型,该函数应该在任何试图提取数据的函数调用之前被调用。SQlite3数据库允许不同类型的数据存储在同一列中,所以对于不同行的相同索引的列调用该函数获取的列类型可能会不同。const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); 返回一个指针,指向给定列的BLOB类型值。double sqlite3_column_double(sqlite3_stmt*, int iCol); 从给定列返回一个64位浮点值。int sqlite3_column_int(sqlite3_stmt*, int iCol); 从给定列返回一个32位有符号整数,如果该列中包含的整型值无法用32位数值表示,那它将会在没有任何警告的情况下被截断。sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); 从给定列返回一个64位有符号整数。const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); 返回一个指针,指向给定列的UTF-8或者UTF-16编码的字符串,该字符串以NULL结尾。sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); 返回一个指针,指向一个无保护的sqlite3_value结构,该结构无法进行安全的数据类型转换,所以无法调用sqlite3_value_xxx函数从这个结构体中提取原始数值。如果想提取原始数值,只能调用其它的sqlite3_column_xxx函数。对于该函数返回的指针,安全的用法是以它为参数调用sqlite3_bind_value函数给一个prepared语句绑定参数,或者以它为参数调用sqlite3_result_value函数得到一个用户自定义的SQL函数的返回值。 对于这些sqlite3_column_xxx函数返回的指针,当再次调用sqlite3_column_xxx函数并操作相同的列的时失效,或者在sqlite3_step、sqlite3_reset、sqlite3_finalize等函数调用之后失效。 如果提取列值时使用的sqlite3_column_xxx函数版本与原始值的本地数据类型不同,SQlite数据库将进行转换。转换原则:int sqlite3_value_bytes(sqlite3_value*); int sqlite3_value_bytes16(sqlite3_value*); 对于BLOB和text类型,sqlite3_column_blob和sqlite3_column_text函数将会返回一个buffer指针。通过sqlite3_value_bytes函数可以得到buffer字节长度,对于text类型,这个字节长度将包括一个字符串结尾符。 需要注意的是:假如先调用sqlite3_column_text函数获取一个指向UTF-8编码的字符串指针,之后又调用了sqlite3_column_bytes16在相同的列上获取buffer大小,那么该列的字符串将会从UTF-8编码转换为UTF-16编码,导致之前由sqlite3_column_text函数返回的指针失效。 正确做法是提取值时的函数和获取值buffer大小的函数,以相同类型匹配使用,如:cpp view plaincopy/* correctly extract a blob */ buf_ptr = sqlite3_column_blob( stmt, n ); buf_len = sqlite3_column_bytes( stmt, n ); /* correctly extract a UTF-8 encoded string */ buf_ptr = sqlite3_column_text( stmt, n ); buf_len = sqlite3_column_bytes( stmt, n ); /* correctly extract a UTF-16 encoded string */ buf_ptr = sqlite3_column_text16( stmt, n ); buf_len = sqlite3_column_bytes16( stmt, n ); 重置与完成(Reset and Finalize)cpp view plaincopyint sqlite3_reset(sqlite3_stmt *pStmt); 当sqlite3_step函数调用返回SQLITE_DONE时,则代表这条语句已经完成执行,这时如果还想重用这条prepared语句,就需要调用sqlite3_reset函数进行重置。或者,比如我们只想提取结果集的前六行数据,那么我们就可以连续调用6次sqlite3_step函数,之后调用sqlite3_reset函数重置prepared语句,以备下一次使用。cpp view plaincopyint sqlite3_finalize(sqlite3_stmt *pStmt); 销毁prepared语句,释放资源。在关闭数据库连接之前,对于不再使用的prepared语句,一定要调用sqlite3_finalize函数进行销毁,语句(状态)转换(Statement Transitions) 一条语句可以处于不同状态,对于一条新的或者刚刚被reset的语句,它们处于“ready”状态,代表它们已经准备好执行,但还没有开始执行。一条语句也有可能处于“running”状态,表明这条语句已经开始执行,但还没有完成。还有一种状态叫做“done”,表明一条语句已经执行完成。 对于有些API函数,只能在某条语句处于特定状态下才可以执行,比如sqlite3_bind_xxx函数,只有在一条语句处于“ready”状态时才可以被调用,否则函数将会返回SQLITE_MISUSE错误码。下图展示了一条语句所处于的不同状态,以及不同状态之间是如何转换的。示例代码(1)cpp view plaincopysqlite3_stmt *stmt = NULL; /* . open database . */ cpp view plaincopyrc = sqlite3_prepare_v2( db, CREATE TABLE tbl ( str TEXT ), -1, &stmt, NULL ); if ( rc != SQLITE_OK) exit( -1 ); cpp view plaincopyrc = sqlite3_step( stmt ); if ( rc != SQLITE_DONE ) exit ( -1 ); sqlite3_finalize( stmt ); /* . close database . */ CREATE TABLE语句没有返回值,调用sqlite3_step函数执行这条语句,最后在关闭数据库之前调用sqlite3_finalize销毁这条语句。(2)cpp view plaincopyconst char *data = NULL; sqlite3_stmt *stmt = NULL; /* . open database . */ cpp view plaincopyrc = sqlite3_prepare_v2( db, SELECT str FROM tbl ORDER BY 1, -1, &stmt, NULL ); if ( rc != SQLITE_OK) exit( -1 ); while( sqlite3_step( stmt ) = SQLITE_ROW ) data = (const char*)sqlite3_column_text( stmt, 0 ); printf( %sn, data ? data : NULL ); sqlite3_finalize( stmt ); /* . close database . */ 这段代码循环提取表tbl的所有行,并把每一行第0列值打印出来。
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 管理文书 > 工作总结


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!