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语句的首指针。
二、预编译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, -, &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子句中的条件进行绑定,这就会影响查询结果,这个语句将会自动被重新编译,类似于数据库的架构改变的情况。
下方是扩展后的结果集:
上面说这么多,就是一句话,在预编译时强烈推荐使用“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()所需参数和返回值
上面已经准备好了预编译好的SQL语句,我们使用sqlite3_step()来执行和遍历一下结果集,具体代码如下:
if (result == SQLITE_OK) {
NSLog(@"查询成功");
//遍历结果集 while (sqlite3_step(statement) == SQLITE_ROW) { int rowNum = sqlite3_column_int(statement, ); char *rowDataOne = (char *) sqlite3_column_text(statement, ); char *rowDataTow = (char *) sqlite3_column_text(statement, ); NSString *nameString = [NSString stringWithUTF8String:rowDataOne]; NSString *firstLetterString = [NSString stringWithUTF8String:rowDataTow]; NSLog(@"BrandId = %d, Name = %@, FirstLetter = %@",rowNum , nameString, firstLetterString); }
sqlite3_finalize(statement); } else {
NSString *error = [NSString stringWithFormat:@"错误结果代码:%d", result]; NSLog(@"%@", error);
}
可以对上面的代码进行一下修改,在while循环语句的最后一条语句后,加上sqllite3_reset(), 那么这个循环就是一个死循环,读取的永远是第一个数据。在这儿就不往上贴代码了。
执行结果如下:
好,今天的数据库查询就先到这儿,关于别的内容,会在下节博客中进行介绍。
iOS开发之SQLite-C语言接口规范(二) —— Prepared Your SQL Statements的更多相关文章
- Ios开发之sqlite
Sqlite是ios数据存储的一个重要手段,今天我们就一块来看一下,怎样使用sqlite将数据存储到沙盒中去. 第一步:导入一个框架libsqlite3.0.dylib 选中TARGETS在Gener ...
- iOS开发之Socket通信实战--Request请求数据包编码模块
实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...
- iOS 开发之Block
iOS 开发之Block 一:什么是Block.Block的作用 UI开发和网络常见功能的实现回调,按钮事件的处理方法是回调方法. 1. 按钮事件 target action 机制. 它是将一 ...
- 李洪强iOS开发之Block和协议
李洪强iOS开发之Block和协议 OC语言BLOCK和协议 一.BOLCK (一)简介 BLOCK是什么?苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任 ...
- 李洪强iOS开发之iOS好文章收集
李洪强iOS开发之iOS好文章收集 该文收集朋友们转发或自己的写的技术文章,如果你也有相关的好文章,欢迎留言,当好文章多的时候,我会对这些好文章进行分门别类 文章 简述 日期 直播服务配置 使用 ng ...
- iOS开发之loadView、viewDidLoad及viewDidUnload的关系
iOS开发之loadView.viewDidLoad及viewDidUnload的关系 iOS开发之loadView.viewDidLoad及viewDidUnload的关系 标题中所说的3个方 ...
- iOS开发之Xcode常用调试技巧总结
转载自:iOS开发之Xcode常用调试技巧总结 最近在面试,面试过程中问到了一些Xcode常用的调试技巧问题.平常开发过程中用的还挺顺手的,但你要突然让我说,确实一脸懵逼.Debug的技巧很多,比如最 ...
- 李洪强iOS开发之iOS社区收集
李洪强iOS开发之iOS社区收集 项目 简述 github 全球最大的代码仓库,无论是iOS开发还是Android开发没有人不知道这个网站,它也是一个社区,你可以去follow(关注)某些人或公司. ...
- 李洪强IOS开发之iOS好项目收集
李洪强IOS开发之iOS好项目收集 在这里收集一些最近出现的比较实用好玩的框架或者项目,会不断更新 项目 简述 日期 SCTableViewCell 类似与QQ侧滑删除Cell的Demo 201501 ...
随机推荐
- java反射学习之二万能EXCEL导出
一.EXCEL导出的实现过程 假设有一个对象的集合,现在需要将此集合内的所有对象导出到EXCEL中,对象有N个属性:那么我们实现的方式是这样的: 循环这个集合,在循环集合中某个对象的所有属性,将这个对 ...
- APP设计资源
在开发独立客户端时,需要一些不同尺寸的图标和图片,统计如下. APP 图标 ICON iOS:(主要需要这三类图标) 58x58 87x87 (Spotlight & Settings) 80 ...
- PMP备考_第六章_项目时间管理
项目时间管理 前言 项目时间管理是项目管理中最难的一个环节,与个人时间管理类似,团体的效率如果管理不当,是低于个人效率的,为了管理好时间,从预估,执行到反馈均需要严格的分析和处理.如果制定的计划是无法 ...
- 移动开发可能用到的css单位
众所周知CSS技术我们虽然很熟悉,在使用的过程却很容易被困住,这让我们在新问题出现的时候变得很不利.随着web继续不断地发展,对于新技术新 解决方案的要求也会不断增长.因此,作为网页设计师和前端开发人 ...
- OS中atomic的实现解析
OS中atomic的实现解析 转自:http://my.oschina.net/majiage/blog/267409 摘要 atomic属性线程安全,会增加一定开销,但有些时候必须自定义ato ...
- 编写一个基本的连接池来实现连接的复用&一些工程细节上的优化
package it.cast.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQL ...
- SQL Server 2016 CTP2.3 的关键特性
SQL Server 2016 CTP2.3 的关键特性 数据库方面的增强 Row Level Security已经支持In-memory OLTP 表.用户现在可以对内存优化表实施row-level ...
- HDFS Client 设计实现解析
前面对 HDFS NameNode 和 DataNode 的架构设计实现要点做了介绍,本文对 HDFS 最后一个主要构成组件 Client 做进一步解析. 流式读取 HDFS Client 为客户端应 ...
- .NET Core 跨平台发布(dotnet publish)
.NET Core 跨平台发布(dotnet publish) ,无需安装.NET Core SDK,就可以运行. 前面讲解了.NET Core 的VSCode 开发.现在来讲讲发布(dotnet p ...
- SQL SERVER全面优化-------索引有多重要?
想了好久索引的重要性应该怎么写?讲原理结构?我估计大部分人不愿意看,也不愿意花那么多时间仔细研究.光写应用?感觉不明白原理一样不会用.举例说明?情况太多也写不全....到底该怎么写呢? 随便写吧,想到 ...