iOS开发之SQLite-C语言接口规范(二) —— Prepared Your SQL Statements

  在《SQLite的C语言接口规范(一)中牵线了什么样去老是打开数据库,本篇博客就介绍怎么样操作数据库,本篇首要给出了怎么履行数据库查询语句(Select),
然后遍历结果集。本篇博客就径直利用上一篇博客封装的开拓数据库的艺术取得到数据库的操作句柄,然后经过这几个句柄来操作我们的Sqlite数据库。前日那篇博客中要多Cars.sqlite数据库中的其中一个表展开Select操作。更为细节的东西请参见SQLite官网:http://www.sqlite.org 。

  一.预编译SQL语句

    要想举行一条查询的SQL语句,需要使用下边任何一个方法先预编译成字节码程序。不难看出以下格局的参数都是一模一样的,那么就先逐一的牵线一下每个参数的象征怎么着。

    1. 参数“sqlite3 * db”, 就是大家调用sqlite3_open(),
sqlite3_open_v2() 或者
sqlite3_open16()成功后获取的操作数据库的句柄。数据库连接必须没有被关门。

    2. zSql是第四个参数, 他的编码格式是UTF-8或UTF-16,
它就是将会被先行编译成字节码的SQL语句。sqlite3_prepare() 和
sqlite3_prepare_v2()接口使用的是UTF-8编码。sqlite3_prepare16() 和
sqlite3_prepare16_v2() 使用的是 UTF-16编码。

    3.
nByte是第七个参数,说白了,它就是参数zSql字符串的最大尺寸。假如nByte是负数,那么zSql的尺寸不限,要是nByte是正数,zSql的长短则不可能超越nByte的数值,超出的部分将不会被预编译。假如nByte是0,那么zSql将不会被预编译。假如你在此以前学过C语言的话,在C语言中是从未所谓的字符串的,是一个对准字符的指针,前面跟了层出不穷字符,以‘\0’结尾,这就是C语言中的字符串,须要经过指针的移动来遍历字符串的,所以nByte是很有必不可少的。

    4. *ppStmt
是预编译语句后右侧的指针,它可以动用sqlite3_step()执行。在发出错误时,*ppStmt就会被装置为NULL。借使输入的文件不是SQL语句(输入的文书为空字符串或者一行注释)*ppStmt就会被安装为NULL。
sqlite3_finalize()负责释放被编译的SQL语句。

    5. pzTail,
看pzTail的品种就可以看看它是指向指针的指针。pzTail指向何人的指针呢?如她不为NULL的话,它就针对预编译SQL语句的结尾,也就是未预编译SQL语句的首指针。  

图片 1

  二、预编译SQL语句实例

  上面是接纳sqlite3_prepare()来预编译的一条查询语句,在新的种类中指出接纳sqlite_prepare_v2(),
他是前者的升级版。v2代表如何看头,在上一篇博客中进行的大概介绍,未来倘诺有时光,会对VFS(虚拟文件系统)举行详细的介绍。

  1.概念NSString类型的SQL查询语句,如下所示:

       //查询数据库
        NSString * qureyInfo = @"SELECT * FROM CARBRAND";

 

  2. 定义sqlite3_stmt变量来经受预编译后的说话。

        sqlite3_stmt *statement;    

 

  3.把NSString类型 SQL语句转成UTF-8的花色。

        const char * zSql = [qureyInfo UTF8String];    

  

  4.调用sqlite3_prepare()举办预编译,sqlite3_prepare()预编译后会有结果状态码,在上一篇博客中举行了教学,本篇博客不做过的废话:

int result = sqlite3_prepare(database, zSql, -1, &statement, nil);

 

  经过地点这几个步骤就可以赢得到预编译后的SQL语句statement,然后我们就足以透过statement做一些爱做的业务了。

 

  三、执行预编译后的SQL语句

    执行预编译后的SQL语句需求调用sqlite3_step()。 sqlite3_step()
会被五遍或频仍实践,由下方截图可见,sqlite3_step()的参数就是预编译后的口舌的指针(sqlite3_stmt
*)。在新的项目中推介应用sqlite3_prepare_v2()和sqlite3_prepare16_v2()。因为要向后万分,所之前面的接口举办了保留,可是,不提议使用sqlite3_prepare()和sqlite3_prepare16()。在“v2”接口中,被再次来到的预编译语句(sqlite3_stmt对象)包涵了一个原始SQL语句的副本。那造成了sqlite3_step()有二种不相同的表现格局。

    1.假诺数据库的Schema爆发变化了,此前会重返SQLITE_SCHEMA,若是使用带v2的艺术的话,sqlite3_step()将电动重新编译SQL语句不偏不倚新尝试运行它。因为运用v2的法子,预编译的结果中校包括SQL原始语句。

    2.当错误爆发时,sqlite3_step()将会回去更为详细的错误代码和增添错误代码。而从前的做法是再次来到一个通用的一无所长结果代码SQLITE_ERROR,而你只可以去调用sqlite3_reset()方法来查找问题。在“v2”预编译接口大校会立时回去错误原因。

    3.假诺一定的值与WHERE子句中的条件举行绑定,那就会影响查询结果,那个讲话将会自行被再度编译,类似于数据库的架构改变的场合。

图片 2

    下方是扩充后的结果集:

图片 3

    上边说这么多,就是一句话,在预编译时强烈推荐使用“v2”预编译接口,“v2”预编译接口是进步版,作用更强劲。

    sqlite3_step()接口去执行预编译后的言语,也会回去一些结出代码,上边介绍一些常用的结果代码:SQLITE_BUSY,
SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR或者
SQLITE_MISUSE,如若你是选择的“v2”接口举行编译的话,将会重回越来越多更为详细的结果编码。

    SQLITE_BUSY
代表数据库引擎不可以赢得所需的数据库锁然后做它的办事。即使语句是commit或实施一个外表的显式事务,你可以重试。若是的语句不是提交并且实施一个之中显示的事务,那么在重试从前您应当回滚事务。

    SQLITE_DONE
意味着语句执行到位同时成功。没有初次调用sqlite3_reset()来重置虚拟机复苏到开始状态,sqlite3_step()就不应该再调用那几个虚拟机。

    SQLITE_ROW
如若正在推行的SQL语句重临任何数据,
为了方便调用者处理,假如有多少,再次来到结果就是SQLITE_ROW。再次sqlite3_step()来寻觅数据的下一行。

    SQLITE_ERROR
出错的情事,你可以调用sqlite3_errmsg()来查阅具体的错误。sqlite3_errmsg()所需参数和再次回到值

图片 4

 

    下面已经准备好了预编译好的SQL语句,大家应用sqlite3_step()来推行和遍历一下结实集,具体代码如下:

 1     if (result == SQLITE_OK) {
 2         NSLog(@"查询成功");
 3         //遍历结果集
 4         
 5         while (sqlite3_step(statement) == SQLITE_ROW) {
 6             
 7             int rowNum = sqlite3_column_int(statement, 0);
 8             
 9             char *rowDataOne = (char *) sqlite3_column_text(statement, 1);
10             
11             char *rowDataTow = (char *) sqlite3_column_text(statement, 2);
12             
13             NSString *nameString = [NSString stringWithUTF8String:rowDataOne];
14             
15             NSString *firstLetterString = [NSString stringWithUTF8String:rowDataTow];
16             
17             NSLog(@"BrandId = %d, Name = %@, FirstLetter = %@",rowNum , nameString, firstLetterString);
18             
19         }
20         sqlite3_finalize(statement);
21         
22     } else {
23         NSString *error = [NSString stringWithFormat:@"错误结果代码:%d", result];
24         
25         NSLog(@"%@", error);
26     }

  可以对地点的代码进行一下修改,在while循环语句的末梢一条语句后,加上sqllite3_reset(),
那么这一个轮回就是一个死循环,读取的世代是第四个数据。在此时就不往上贴代码了。 

  执行结果如下:

       
 图片 5图片 6

 

  好,后天的数据库查询就先到此刻,关于其余内容,会在下节博客中开展介绍。    

网站地图xml地图