sqlite3 零基础入门

sqlite3使用简介

一 . 使用的流程

   要使用sqlite,需要将libsqlite3.0.dylib导入到工程的配置文件中.

  使用过程中的函数大致分为如下几个:

  > sqlite3_open()

  > sqlite3_prepare()

  > sqlite3_step()

  > sqlite3_column()

  > sqlite3_finalize()

  > sqlite3_colse()

  这几个过程是概念上的说法,而不完全是程序运行的过程,如sqlite3_column()表示的是对查询获得一行里面的数据的列的各个操作统

称, 实际上在sqlite中并不存在这个函数.

  1.sqlite3_open()  打开数据库

  在操作数据库之前,首先要打开数据库,这个函数打开一个sqlite数据库文件的链接并且返回一个数据库链接对象.这个操作是程序中第一

个调用的sqlite函数,同时也是其他sqlite API 的先决条件.许多的sqlite接口函数都需要一个数据库链接对象的指针作为它们的第一个参数.

  函数的定义-----(针对不同的编码及参数,官方文档给了一下三种定义)

  int sqlite3_open(

   const char *filename,   /* UTF8 */

   sqlite3 **ppDb             /* SQLite db handle */

  );

  int sqlite3_open16(

   const void *filename,   /* UTF16 */

   sqlite3 **ppDb             /* SQLite db handle */

  );

  int sqlite3_open_v2(

   const char *filename,   /* UTF8 */

   sqlite3 **ppDb,            /* SQLite db handle */

  int flags,                       /* Flags */

  const char * zVfs           /* Name of VFS module to use */

  );

  补充说明:

  假如这个要被打开的数据库文件不存在,则一个同名的数据库文件将被创建.

  返回值:

  如果sqlite数据库被成功打开(或创建),将会返回SQLITE_OK,否则将会返回错误码. sqlite3_errmsg() 或者 sqlite3_errmsg16()

可以用来获得数据库打开错误码的英文描述,这两个函数的定义为 :

  const char * sqlite3_errmsg(sqlite3*);

  const void * sqlite3_errmsg16(sqlite3*);

  参数说明 :

  filename : 需要被打开的数据库文件的文件名,在sqlite3_open 和 sqlite3_open_v2中这个参数采用UTF-8编码,而在sqlite3_open16

中,则采用UTF-16编码方式.

  ppDb : 一个数据库链接句柄将会返回到这个参数,如果发生错误的话,ppDb将会返回一个NULL值

  flags : 作为数据库链接的额外控制的参数,可以是SQLITE_OPEN_READONLY,SQLITE_OPEN_READWRITE和SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE中的一个,用于控制数据库的打开方式,可以和SQLITE_OPEN_NOMUTEXSQLITE_OPEN_FULLMUTEX, SQLITE_OPEN_SHAREDCACHE,以及SQLITE_OPEN_PRIVATECACHE结合使用,具体的详细情况可以查阅文档

  2.sqlite3_prepare()

  这个函数将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针。这个接口需要一个数据库连接指针以及一个要准备的包含SQL语句的文本。它实际上并不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句

函数定义(仅列出UTF-8的)

  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 */

  );

  

  参数:

  db:数据指针

  zSql:sql语句,使用UTF-8编码

  nByte:如果nByte小于0,则函数取出zSql中从开始到第一个0终止符的内容;如果nByte不是负的,那么它就是这个函数能从zSql中读取的字节数的最大值。如果nBytes非负,zSql在第一次遇见’/000/或’u000’的时候终止

  pzTail:上面提到zSql在遇见终止符或者是达到设定的nByte之后结束,假如zSql还有剩余的内容,那么这些剩余的内容被存放到pZTail中,不包括终止符

  ppStmt:能够使用sqlite3_step()执行的编译好的准备语句的指针,如果错误发生,它被置为NULL,如假如输入的文本不包括sql语句。调用过程必须负责在编译好的sql语句完成使用后使用sqlite3_finalize()删除它。

  说明

  如果执行成功,则返回SQLITE_OK,否则返回一个错误码。推荐在现在任何的程序中都使用sqlite3_prepare_v2这个函数,sqlite3_prepare只是用于前向兼容

  备注

  <1>准备语句(prepared statement)对象

  typedef struct sqlite3_stmt sqlite3_stmt;

  准备语句(prepared statement)对象一个代表一个简单SQL语句对象的实例,这个对象通常被称为“准备语句”或者“编译好的SQL语句”或者就直接称为“语句”。

语句对象的生命周期经历这样的过程:

  l  使用sqlite3_prepare_v2或相关的函数创建这个对象

  l  使用sqlite3_bind_*()给宿主参数(host parameters)绑定值

  l  通过调用sqlite3_step一次或多次来执行这个sql

  l  使用sqlite3——reset()重置这个语句,然后回到第2步,这个过程做0次或多次

  l  使用sqlite3_finalize()销毁这个对象

  在sqlite中并没有定义sqlite3_stmt这个结构的具体内容,它只是一个抽象类型,在使用过程中一般以它的指针进行操作,而sqlite3_stmt类型的指针在实际上是一个指向Vdbe的结构体得指针

  <2>宿主参数(host parameters)

  在传给sqlite3_prepare_v2()的sql的语句文本或者它的变量中,满足如下模板的文字将被替换成一个参数:

  l  ?

  l  ?NNN,NNN代表数字

  l  :VVV,VVV代表字符

  l  @VVV

  l  $VVV

  在上面这些模板中,NNN代表一个数字,VVV代表一个字母数字标记符(例如:222表示名称为222的标记符),sql语句中的参数(变量)通过上面的几个模板来指定,如

  “select ? from ? “这个语句中指定了两个参数,sqlite语句中的第一个参数的索引值是1,这就知道这个语句中的两个参数的索引分别为1和2,使用”?”的话会被自动给予索引值,而使用”?NNN”则可以自己指定参数的索引值,它表示这个参数的索引值为NNN。”:VVV”表示一个名为”VVV”的参数,它也有一个索引值,被自动指定。

  可以使用sqlite3_bind_*()来给这些参数绑定值

  

  3.  sqlite3_setp()

  这个过程用于执行有前面sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调用sqlite3_setp()。继续调用sqlite3_setp()知道这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只执行一次就返回

  函数定义

  int sqlite3_step(sqlite3_stmt*);

  返回值

  函数的返回值基于创建sqlite3_stmt参数所使用的函数,假如是使用老版本的接口sqlite3_prepare()和sqlite3_prepare16(),返回值会是 SQLITE_BUSY, SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR 或 SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()则会同时返回这些结果码和扩展结果码。

  对所有V3.6.23.1以及其前面的所有版本,需要在sqlite3_step()之后调用sqlite3_reset(),在后续的sqlite3_ step之前。如果调用sqlite3_reset重置准备语句失败,将会导致sqlite3_ step返回SQLITE_MISUSE,但是在V3. 6.23.1以后,sqlite3_step()将会自动调用sqlite3_reset。

  int sqlite3_reset(sqlite3_stmt *pStmt);

  sqlite3_reset用于重置一个准备语句对象到它的初始状态,然后准备被重新执行。所有sql语句变量使用sqlite3_bind*绑定值,使用sqlite3_clear_bindings重设这些绑定。Sqlite3_reset接口重置准备语句到它代码开始的时候。sqlite3_reset并不改变在准备语句上的任何绑定值,那么这里猜测,可能是语句在被执行的过程中发生了其他的改变,然后这个语句将它重置到绑定值的时候的那个状态。

  4.  sqlite3_column()

    这个过程从执行sqlite3_step()执行一个准备语句得到的结果集的当前行中返回一个列。每次sqlite3_step得到一个结果集的列停下后,这个过程就可以被多次调用去查询这个行的各列的值。对列操作是有多个函数,均以sqlite3_column为前缀

  const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);

  int sqlite3_column_bytes(sqlite3_stmt*, int iCol);

  int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);

  double sqlite3_column_double(sqlite3_stmt*, int iCol);

  int sqlite3_column_int(sqlite3_stmt*, int iCol);

  sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);

  const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

  const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);

  int sqlite3_column_type(sqlite3_stmt*, int iCol);

  sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);

  说明

  第一个参数为从sqlite3_prepare返回来的prepared statement对象的指针,第二参数指定这一行中的想要被返回的列的索引。最左边的一列的索引号是0,行的列数可以使用sqlite3_colum_count()获得。

  这些过程会根据情况去转换数值的类型,sqlite内部使用sqlite3_snprintf()去自动进行这个转换,下面是关于转换的细节表:

  

  注:BLOB数据类型是指二进制的数据块,比如要在数据库中存放一张图片,这张图片就会以二进制形式存放,在sqlite中对应的数据类型就是BLOB

  

  int sqlite3_column_bytes(sqlite3_stmt*, int iCol)int sqlite3_column_bytes16(sqlite3_stmt*, int iCol)两个函数返回对应列的内容的字节数,这个字节数不包括后面类型转换过程中加上的0终止符。

  下面是几个最安全和最简单的使用策略

  > 先sqlite3_column_text() ,然后 sqlite3_column_bytes()

  > 先sqlite3_column_blob(),然后sqlite3_column_bytes()

  > 先sqlite3_column_text16(),然后sqlite3_column_bytes16()

  

5.  sqlite3_finalize

int sqlite3_finalize(sqlite3_stmt *pStmt);

这个过程销毁前面被sqlite3_prepare创建的准备语句,每个准备语句都必须使用这个函数去销毁以防止内存泄露。

在空指针上调用这个函数没有什么影响,同时可以准备语句的生命周期的任一时刻调用这个函数:在语句被执行前,一次或多次调用sqlite_reset之后,或者在sqlite3_step任何调用之后不管语句是否完成执行

  6.  sqlite3_close

  这个过程关闭前面使用sqlite3_open打开的数据库连接,任何与这个连接相关的准备语句必须在调用这个关闭函数之前被释放

  

  二 . 使用举例

之前都是保存在 document  最近保存在document 苹果不允许上传
    保存在缓存里边
    NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
    拼接文件名
    path = [path stringByAppendingPathComponent:@"student.sqlite"];
    NSLog(@"%@",path);
    
    打开数据库 ,创建数据库文件
    filename  保存数据库的全路径文件名
    ppDb  数据库实例
    sqlite3 *db = nil;
    if (sqlite3_open([path UTF8String], &_db) == SQLITE_OK) {
        NSLog(@"打开成功");
    }else{
        NSLog(@"打开失败");
    }
    创建表
    第一个参数 :数据库实例
    第二个参数 : 执行那个的数据库语句
    NSString *sql = @"create table if not exists t_student (  id integer primary key autoincrement ,name text ,age integer);";
    [self execSqlWithString:sql];

      NSString *sql = @"select *from t_student ;";
    准备查询
    数据库语句字节数   -1 表示自动计算字节数
    ppStmt 句柄 : 用来操作查询的语句
    sqlite3_stmt *stmt;
    if (sqlite3_prepare(_db, sql.UTF8String, -1, &stmt, NULL) ==SQLITE_OK) {
        准备成功
        执行句柄
        while(sqlite3_step(stmt) == SQLITE_ROW) {
            int ID = sqlite3_column_int(stmt, 0);
          NSString *name = [NSString stringWithUTF8String: (const char *)sqlite3_column_text(stmt, 1)];
            NSLog(@"%d -- %@",ID,name);
        }
    }

  

  sqlite3_exec是sqlite3_prepare_v2,sqlite3_step()和sqlite3_finalize()的封装,能让程序多次执行sql语句而不要写许多重复的代码。

  Sqlite3_exec接口执行0或多个UTF-8编码的,分号分割的sql语句,传到第二个参数中。如果sqlite3_exec的第三个参数回调函数指针不为空,那么它会为每个来自执行的SQL语句的结果行调用(也就是说回调函数会调用多次,上面例子中会返回2个结果行,因而会被执行2次),第4个参数是传给回调函数的第一个参数,如果回调函数指针为空,那么回调不会发生同时结果行被忽略。

  如果在执行sql语句中有错误发生,那么当前的语句的执行被停止,后续的语句也被跳过。第五个参数不为空的时候,它被分配内存并写入了错误信息,所以在sqlite3_exec后面需要调用sqlite3_free去释放这个对象以防止内存泄露

  回调函数:

  int (*callback)(void*,int,char**,char**),  /* Callback function */

第一个参数通过sqlite3_exec的第第四个参数传入的

第二个参数是结果行的列数

第三个参数是行中列数据的指针

第四个参数是行中列名称的指针

时间: 2024-10-02 13:15:39

sqlite3 零基础入门的相关文章

从零基础入门JavaScript(1)

从零基础入门JavaScript(1) 1.1  Javascript的简史 1995年的时候   由网景公司开发的,当时的名字叫livescript    为了推广自己的livescript,搭了java顺风车,改名为javascript 与此同时,     微软因此在自身的浏览器里,也推出了自己的脚本语言 jscript 1997年时候,  由ECMA(欧洲计算机制造商协会)出面,推出了一套javascript的规范,Ecmascript ,规范提出js由三部分组成 JS的组成: ECMAS

鱼C《零基础入门学习Python》10-17节课时知识点总结

第10讲:列表:一个打了激素的数组 1. 列表都可以存放一些什么东西?  我们说 Python 的列表是一个打了激素的数组,如果把数组比喻成集装箱,那么 Python 的列表就是一个大仓库,Ta 可以存放我们已经学习过的任何数据类型. 2. 向列表增加元素有哪些方法?  三种方法想列表增加元素,分别是:append().extend() 和 insert().    3. append() 方法和 extend() 方法都是向列表的末尾增加元素,请问他们有什么区别?  append() 方法是将

Linux及Arm-Linux程序开发笔记(零基础入门篇)

Linux及Arm-Linux程序开发笔记(零基础入门篇)  作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/beer/archive/2011/05/05/2037449.html 目录 一.Arm-Linux程序开发平台简要介绍... 3 1.1程序开发所需系统及开发语言... 3 1.2系统平台搭建方式... 4 二.Linux开发平台搭建... 5 2.1安装虚拟工作站... 5 2.2安装Linux虚拟

.NET零基础入门05:委托与事件

一:前言 本小节,我们需要停一停我们的小游戏开发,虽然它现在还不完美,还很简单,甚至还有BUG.但是,为了更好的理解C#,现在到了该深入了解一些基础知识的时候了. 当然,实际上,本小节内容对于零基础入门的初学者来说,还是有点难了.委托与事件,如果只是泛泛的说一下,可能就是一两句话.但是,我们的课程要遵循一个原则:知其然,知其所以然.所以,本小节的内容实际上有点多,但是我希望大家细细品味,争取彻底消化委托和事件这两个概念. 同时,本课程还要教会大家使用一个工具,分析代码. 二:委托的现实场景:卖家

零基础入门jQuery视频教程

零基础入门jQuery最新版开发.NET富客户端应用(选择器.DOM操作.事件和动画.Ajax应用.插件.Mobile)课程分类:.NET+Jquery适合人群:初级课时数量:35课时用到技术:javascript,ajax,jquery,handler涉及项目:各知识点的项目案例和名为JaneShop的品牌服装和包包的购物网站咨询qq:1840215592 零基础入门jQuery视频教程详细查看:http://www.ibeifeng.com/goods-425.html 零基础入门jQuer

干货分享:MySQL零基础入门视频教程!

首先给大家介绍一下数据库工程师,数据库工程师(Database Engineer),是从事管理和维护数据库管理系统(DBMS) 的相关工作人员的统称,他属于运维工程师的一个分支,主要负责业务数据库从设计.测试到部署交付的全生命周期管理.数据库工程师的核心目标是保证数据库管理系统的稳定性.安全性.完整性和高性能. 今天在这里给大家分享一个干货教程,MySQL零基础入门视频教程,希望能帮助到大家! 课程目录: 一. MySQL课程介绍和MySQL的基础概念(1)二. MySQL基础概念之存储引擎(2

Cloudera Manager、CDH零基础入门、线路指导 http://www.aboutyun.com/thread-9219-1-1.html (出处: about云开发)

Cloudera Manager.CDH零基础入门.线路指导http://www.aboutyun.com/thread-9219-1-1.html(出处: about云开发) 问题导读:1.什么是cloudera CM .CDH?2.CDH.CM有哪些版本?3.CDH.CM有哪些安装方式?4.CDH如何开发? <ignore_js_op> 我们知道cloudera CDH 是为简化hadoop的安装,也对对hadoop做了一些封装.那么我们就像尝试学习cloudera.cloudera本质h

.NET零基础入门09:SQL必知必会

一:前言 仿佛到了更进一步的时候了,每一个程序员迟早都会遇到数据存储的问题.我们拿什么来存储程序产生的数据?举例来说,用什么来存储我们的打老鼠游戏每次的成绩呢?选择如下: 1:内存中.缺点,退出游戏,数据就没了: 2:文件中.好办法!缺点,自己解析文本,把文本变成我们程序中的数据,这个解析的过程叫做协议.协议这个词听上去够恐怖吧,实际上说白了无非就是数据格式怎么样,API接口怎么样之类的东东. 3:数据库.好办法!好吧,数据库文件其实也就是硬盘上的文件,只不过数据库本身就已经为我们定义好了数据格

鱼C《零基础入门学习Python》1—9节课时知识点总结

第一节:我和python的第一次亲密接触 0. Python 是什么类型的语言? 答:脚本语言(Scripting language)是电脑编程语言,因此也能让开发者藉以编写出让电脑听命行事的程序.以简单的方式快速完成某些复杂的事情通常是创造脚本语言的重要原则,基于这项原则,使得脚本语言通常比 C语言.C++语言 或 Java 之类的系统编程语言要简单容易.也让脚本语言另有一些属于脚本语言的特性: 语法和结构通常比较简单 学习和使用通常比较简单 通常以容易修改程序的“解释”作为运行方式,而不需要