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, -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子句中的条件进行绑定,这就会影响查询结果,这个语句将会自动被重新编译,类似于数据库的架构改变的情况。

    下方是扩展后的结果集:

    上面说这么多,就是一句话,在预编译时强烈推荐使用“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, 0);
            
            char *rowDataOne = (char *) sqlite3_column_text(statement, 1);
            
            char *rowDataTow = (char *) sqlite3_column_text(statement, 2);
            
            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(), 那么这个循环就是一个死循环,读取的永远是第一个数据。在这儿就不往上贴代码了。 

  执行结果如下:

         

 

  好,今天的数据库查询就先到这儿,关于别的内容,会在下节博客中进行介绍。    

相关文章
|
1天前
|
编解码 安全 Android开发
探索iOS与Android开发的差异:从界面到性能
【6月更文挑战第10天】在移动应用开发的广阔天地中,iOS和Android两大平台各占山头,它们在设计理念、用户体验、性能优化等方面展现出独特的魅力。本文将深入探讨这两大系统在开发过程中的主要差异,从用户界面设计到性能调优,揭示各自背后的技术逻辑与创新策略,为开发者提供全面的视角和实用的开发指南。
|
2天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异性
【6月更文挑战第9天】本文深入探讨了安卓和iOS这两大主流移动操作系统在应用程序开发方面的关键差异。从编程语言、用户界面设计到市场策略,我们将逐一分析这些差异如何影响开发者的选择和最终产品的用户体验。通过比较,我们旨在为开发者提供一份实用的指南,帮助他们在这两个平台上做出更明智的开发决策。
|
3天前
|
前端开发 搜索推荐 iOS开发
探索iOS开发的新纪元:SwiftUI的革命性影响
【6月更文挑战第8天】随着苹果公司推出SwiftUI,iOS开发领域迎来了一场创新风暴。本文将深入探讨SwiftUI如何简化界面构建流程,提升开发者效率,并分析其对现有开发模式的颠覆性影响。我们将通过具体案例,展示SwiftUI在实际开发中的应用和优势。
|
4天前
|
开发框架 开发工具 Swift
探索iOS开发的未来:SwiftUI的革命性影响
【6月更文挑战第7天】随着苹果公司不断推进其软件开发工具,SwiftUI作为一个全新的用户界面构建框架,正在重塑iOS应用开发的面貌。本文将深入探讨SwiftUI如何简化设计过程,提升开发效率,并预测其对iOS生态系统的长远影响。
|
4天前
|
人工智能 vr&ar 数据安全/隐私保护
探索iOS开发的未来趋势
【6月更文挑战第7天】本文将深入探讨iOS开发的未来发展,包括SwiftUI的崛起、AR/VR技术的融合、人工智能的集成以及隐私保护的重要性。我们还将讨论这些趋势如何影响开发者的工作方式和用户体验。
|
26天前
|
SQL API 流计算
实时计算 Flink版产品使用合集之在Mac M1下的Docker环境中开启SQL Server代理的操作步骤是什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
2天前
|
SQL DataWorks NoSQL
DataWorks产品使用合集之如何将SQL Server中的数据转存到MongoDB
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
20天前
|
SQL 存储 搜索推荐
SQL server增删改查(1)
SQL server增删改查(1)
30 0
|
20天前
|
SQL 关系型数据库 数据库
阿里云数据库 RDS SQL Server版实战【性能优化实践、优点探析】
本文探讨了Amazon RDS SQL Server版在云数据库中的优势,包括高可用性、可扩展性、管理便捷、安全性和成本效益。通过多可用区部署和自动备份,RDS确保数据安全和持久性,并支持自动扩展以适应流量波动。可视化管理界面简化了监控和操作,而数据加密和访问控制等功能保障了安全性。此外,弹性计费模式降低了运维成本。实战应用显示,RDS SQL Server版能有效助力企业在促销高峰期稳定系统并保障数据安全。阿里云的RDS SQL Server版还提供了弹性伸缩、自动备份恢复、安全性和高可用性功能,进一步优化性能和成本控制,并与AWS生态系统无缝集成,支持多种开发语言和框架。
80 2
|
20天前
|
SQL JSON atlas
实时计算 Flink版产品使用合集之SQL Server CDC是否支持抽取SQL Server视图
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。