SQLite的教程(十四):C语言编程实例代码(2)
三。高效批量数据插入:在操作步骤帮助您阅读后续的示例代码之前,简要介绍了批插入的概念。实际上,批量插入不是一个新概念。它在其他关系数据库的C接口API提供了一些支持,但接口的方式是不同的。在许多流行的数据库接口,如OCI(Oracle,MySQL和PostgreSQL API)API,API,OCI提供最方便的编程接口和实现的最有效的途径。作为一种简单、灵活的嵌入式数据库,SQLite也提供了这个功能,但实现的方式是不为其他数据库一样方便和明显的。它只通过隐藏的技巧达到批量插入的目的。其逻辑如下:
1)。开始一件事确保以下数据操作语句在这件事情完成。在SQLite,如果没有手动开启的一个东西,在自动提交模式下所有的DML语句的工作。每次操作后,数据自动提交并写入磁盘文件。然而,在非自动提交模式,只有当事情是手动提交,将修改后的数据写入磁盘,修改后的数据之前,只驻留在内存中。很明显,这样一批写作方法必然会被远远优于单写操作多个迭代。
2)基于变量绑定的方式准备将数据插入,它可以节省大量的sqlite3_prepare_v2函数调用,从而节省编写相同的SQL语句SQLite内部识别字节的时间。事实上,SQLite的官方文件中已明确指出,在许多情况下,对sqlite3_prepare_v2功能执行时间比sqlite3_step功能。因此,建议用户应避免重复调用sqlite3_prepare_v2功能。在我们的实现中,如果我们想避免这些费用,我们只需要将数据插入变量形式的SQL语句。所以SQL语句只需要调用sqlite3_prepare_v2函数编译一次,然后操作只是更换不同的变量值。
3)。显式提交的所有数据插入完成后,提交后,SQLite会自动恢复当前连接到自动提交模式。
以下是示例代码的实现步骤:
1)。创建测试数据表。
2)。通过执行开始事务语句手动打开一个东西。
3)。准备INSERT语句和相关的绑定变量。
4)。迭代插入数据。
5)。在执行提交语句完成提交事务之后。
6)。删除测试表。
请看下面的代码和关键注释:
复制代码代码如下所示:
#包括
#包括
#包括
使用名称空间;
dotest(无效)
{
sqlite3 * conn = null;
//1. 打开数据库
int结果= sqlite3_open(D: / mytest。DB
如果(结果)!= sqlite_ok){
sqlite3_close(CONN);
返回;
}
const char * createtablesql = =
创建数据表(int_col int,float_col房,string_col文本);
sqlite3_stmt *支撑= null;
int len = strlen(createtablesql);
2。准备创建一个数据表,如果创建失败,你需要释放sqlite3_stmt对象sqlite3_finalize防止内存泄漏。
如果(sqlite3_prepare_v2(Conn,createtablesql,Len,支撑,空)!= sqlite_ok){
如果(支撑)
sqlite3_finalize(支撑);
sqlite3_close(CONN);
返回;
}
3。执行该语句创建表通过sqlite3_step命令,DDL和DML语句的执行,sqlite3_step正确的返回值
只有选择 / / sqlite_done,查询,如果返回的数据sqlite_row,当到达结果集的结束返回
/ / sqlite_done。
如果(sqlite3_step(支撑)!= sqlite_done){
sqlite3_finalize(支撑);
sqlite3_close(CONN);
返回;
}
4。释放资源以创建表语句对象。
sqlite3_finalize(支撑);
printf(成功创建测试表了。;
5。显式打开一个东西。
sqlite3_stmt * stmt2 = null;
const char * beginsql =开始交易;
如果(sqlite3_prepare_v2(Conn,beginsql,strlen(beginsql),stmt2,null)!= sqlite_ok){
如果(stmt2)
sqlite3_finalize(stmt2);
sqlite3_close(CONN);
返回;
}
如果(sqlite3_step(stmt2)!= sqlite_done){
sqlite3_finalize(stmt2);
sqlite3_close(CONN);
返回;
}
sqlite3_finalize(stmt2);
//6. 根据绑定变量构建插入数据。
const char * insertsql =插入数据值(,,);
sqlite3_stmt * stmt3 = null;
如果(sqlite3_prepare_v2(Conn,insertsql,strlen(insertsql),stmt3,null)!= sqlite_ok){
如果(stmt3)
sqlite3_finalize(stmt3);
sqlite3_close(CONN);
返回;
}
国际insertcount = 10;
const char * strdata =这是一个测试。;
7。基于现有SQL语句,迭代绑定不同的变量数据
为(int i = 0;i < insertcount;+ +我){
当绑定到变量索引值的左边是1时。
sqlite3_bind_int(stmt3,1,我);
sqlite3_bind_double(stmt3,2,我* 1);
sqlite3_bind_text(stmt3,3,strdata,strlen(strdata),sqlite_transient);
如果(sqlite3_step(stmt3)!= sqlite_done){
sqlite3_finalize(stmt3);
sqlite3_close(CONN);
返回;
}
/ /重新初始化变量的sqlite3_stmt对象。
sqlite3_reset(stmt3);
printf(插入成功。;
}
sqlite3_finalize(stmt3);
8。提交东西之前。
const char * commitsql =提交;
sqlite3_stmt * stmt4 = null;
如果(sqlite3_prepare_v2(Conn,commitsql,strlen(commitsql),stmt4,null)!= sqlite_ok){
如果(stmt4)
sqlite3_finalize(stmt4);
sqlite3_close(CONN);
返回;
}
如果(sqlite3_step(stmt4)!= sqlite_done){
sqlite3_finalize(stmt4);
sqlite3_close(CONN);
返回;
}
sqlite3_finalize(stmt4);
9。为了方便下一次测试运行,我们需要删除这个函数创建的数据表,否则将无法运行下一次运行。
创建表,因为它已经存在。
const char * dropsql =数据表;
sqlite3_stmt * stmt5 = null;
如果(sqlite3_prepare_v2(Conn,dropsql,strlen(dropsql),stmt5,null)!= sqlite_ok){
如果(stmt5)
sqlite3_finalize(stmt5);
sqlite3_close(CONN);
返回;
}
如果(sqlite3_step(stmt5)= = sqlite_done){
printf(试验台已经下降了。;
}
sqlite3_finalize(stmt5);
sqlite3_close(CONN);
}
主()
{
dotest();
返回0;
}
输出结果如下:
现在成功地创建测试表。
插入成功。
插入成功。
插入成功。
插入成功。
插入成功。
插入成功。
插入成功。
插入成功。
插入成功。
插入成功。
测试表已被删除。
结果与上一个示例(普通数据插入)的结果完全相同,但在执行效率上明显优于前者。
四。数据查询:
数据查询是一个关系数据库将提供最基本的功能,和下面的代码示例将给你如何得到数据通过SQLite API。
1)。创建测试数据表。
2)。将测试数据插入到数据表中以备以后查询。
3)。执行SELECT语句检索数据。
4)。删除测试表。
请参见下面的示例代码和键注释:
复制代码代码如下所示:
#包括
#包括
#包括
使用名称空间;
dotest(无效)
{
sqlite3 * conn = null;
//1. 打开数据库
int结果= sqlite3_open(D: / mytest。DB
如果(结果)!= sqlite_ok){
sqlite3_close(CONN);
返回;
}
const char * createtablesql = =
创建数据表(int_col int,float_col房,string_col文本);
sqlite3_stmt *支撑= null;
int len = strlen(createtablesql);
2。准备创建一个数据表,如果创建失败,你需要释放sqlite3_stmt对象sqlite3_finalize防止内存泄漏。
If (sqlite3_prepare_v2 (Conn, createTableSQL, len, stmt, NULL)! = sqlite_ok){
如果(支撑)
sqlite3_finalize(支撑);
sqlite3_close(CONN);
返回;
}
3。执行该语句创建表通过sqlite3_step命令,DDL和DML语句的执行,sqlite3_step正确的返回值
只有选择 / / sqlite_done,查询,如果返回的数据sqlite_row,当到达结果集的结束返回
/ / sqlite_done。
如果(sqlite3_step(支撑)!= sqlite_done){
sqlite3_finalize(支撑);
sqlite3_close(CONN);
返回;
}
4。释放资源以创建表语句对象。
sqlite3_finalize(支撑);
printf(成功创建测试表了。;
5。为后续的查询操作插入测试数据。
sqlite3_stmt * stmt2 = null;
const char * insertsql =插入值(20,21.0数据,这是一个考验。);
如果(sqlite3_prepare_v2(Conn,insertsql,strlen(insertsql),stmt2,null)!= sqlite_ok){
如果(stmt2)
sqlite3_finalize(stmt2);
sqlite3_close(CONN);
返回;
}
如果(sqlite3_step(stmt2)!= sqlite_done){
sqlite3_finalize(stmt2);
sqlite3_close(CONN);
返回;
}
printf(成功插入测试数据。;
sqlite3_finalize(stmt2);
6。执行SELECT语句来查询数据。
const char *递给李四=SELECT * FROM TestTable表;
sqlite3_stmt * stmt3 = null;
如果(sqlite3_prepare_v2(Conn,递给李四,strlen(递给李四),stmt3,null)!= sqlite_ok){
如果(stmt3)
sqlite3_finalize(stmt3);
sqlite3_close(CONN);
返回;
}
int需要比较的字段为sqlite3_column_count(stmt3);
{做
int r = sqlite3_step(stmt3);
如果(R = = sqlite_row){
为(int i = 0;i < fieldcount;+ +我){
在这里,您需要根据使用不同API函数的返回类型来确定当前的记录/当前字段类型。
获取实际的数据值。
Int Vtype = sqlite3_column_type(stmt3,我);
如果(V = = sqlite_integer){
int v = sqlite3_column_int(stmt3,我);
printf(整数值%d。
否则如果}(V = = sqlite_float){
双V = sqlite3_column_double(stmt3,我);
printf(双值为F
否则如果}(V = = sqlite_text){
const char * V =(const char *)sqlite3_column_text(stmt3,我);
printf(%s的文本价值
否则如果}(V = = sqlite_null){
printf(这个值是零。;
}
}
否则如果}(R = = sqlite_done){
printf(选择完成。;
打破;
{人}
printf(没有选择。;
sqlite3_finalize(stmt3);
sqlite3_close(CONN);
返回;
}
虽然(真)};
sqlite3_finalize(stmt3);
7。为了方便下一次测试运行,我们需要删除这个函数创建的数据表,否则将无法运行下一次运行。
创建表,因为它已经存在。
const char * dropsql =数据表;
sqlite3_stmt * stmt4 = null;
如果(sqlite3_prepare_v2(Conn,dropsql,strlen(dropsql),stmt4,null)!= sqlite_ok){
如果(stmt4)
sqlite3_finalize(stmt4);
sqlite3_close(CONN);
返回;
}
如果(sqlite3_step(stmt4)= = sqlite_done){
printf(试验台已经下降了。;
}
sqlite3_finalize(stmt4);
sqlite3_close(CONN);
}
主()
{
dotest();
返回0;
}
输出结果如下:
现在成功地创建测试表。
成功插入测试数据。
整数值为20。
双值为21。
/文本值是这是一个测试。
/ /选择完成。
测试表已被删除。