1.SQL访问数据库非常方便,只需简单的三个函数:
  sqlite3_open(char* szDbFileName, sqlite3 ** db) 
  sqlite3_exec(sqlite3 *db, char* szSqlCMD, callback, 0, char **zErrMsg)
  sqlite3_close(sqlite3 *db)
  static int callback(void *NotUsed, int argc, char **argv, char **azColName)
2.sqlite3_exec(),执行SQL命令:

int sqlite3_exec(
    sqlite3* db,     /* An open database */
    const char *sql, /* SQL to be executed */
    sqlite_callback, /* Callback function 回调函数名*/
    void *data       /* 1st argument to callback function 传给回调函数的第一个参数*/
    char **errmsg    /* Error msg written here */
); 

  sqlite3_exec()包含一个回叫(callback)机制,提供了一种从SELECT语句得到结果的方法。

  sqlite3_exec()函数第3个参数是一个指向回叫函数的指针,如果提供了回叫函数,SQLite则会在执行SELECT语句时为遇到的每一条记录都调用回叫函数,即sqlite3_exec()执行一条SQL语句,每返回一个结果,就执行一次sqlite_callback函数,方便我们对查询到的数据进行处理。

3.callback()即回叫函数,传给sqlite3_exec的回调函数,用来显示查询结果,对每一条查询结果调用一次该回调函数:
typedef int (*sqlite3_callback)(
    void* data,     /* Data provided in the 4th argument of sqlite3_exec() 由sqlite3_exec()的第4个参数传递*/
    int ncols,      /* The number of columns in row 查询语句返回的字段数目,即表头列数*/
    char** values,  /* An array of strings representing fields in the row 查询到的一条记录的各字段值,包含查找到的所有数据*/
    char** headers  /* An array of strings representing column names 对应列的字段名*/
);   

参数

  data:sqlite3_exec()传入的第四个参数(this指针),通过data参数,可以传入一些特殊的指针(如类指针、结构指针),然后在这里强制转换成对应的类型(这里是void*类型,必须强制转换成该类型才可用)。sqlite3_exec()和callback()都具有这个形式参数,此参数用处巨大,可以传递一个对象的指针给callback函数,再把void* 强制转换成原来的类型,进行一些操作,比如压栈。
  values:是查询记录的数据数组指针,指向查询结果的指针数组, 可以由 sqlite3_column_text() 得到。
  headers:是表头的列名数组指针,指向表头名的指针数组, 可以由 sqlite3_column_name() 得到。

返回值为0或1:

  返回零:sqlite3_exec()将继续执行查询。
  返回非零:sqlite3_exec()将立即中断查询,且sqlite3_exec()将返回SQLITE_ABORT。

回调函数传参示例

Table
ID    NAME    ADDRESS    AGE
1     YSP     ShangHai   22
2     HHB     ShangHai   25

select * from Table

查询到第一条记录,回叫函数被调用一次:
  ncols = 4 (总共4个字段)
  values[0]:“1”;values[1]:“YSP”;values[2]:“ShangHai”;values[3]:“22”   headers[0]:“ID”;headers[1]:“NAME”;headers[2]:“ADDRESS”;headers[3]:“AGE” 

查询到第二条记录,回叫函数被调用第二次:   ncols = 4 (总共4个字段)   values[0]:“1”;values[1]:HHB;values[2]:ShangHai;values[3]:25   headers[0]:ID;headers[1]:NAME;headers[2]:ADDRESS;headers[3]:AGE

注意:sqlite3_exec()查询到的值都是char*类型,可能需要做类型转换,以满足要求。

   如果某列的数据类型不是char*, 则可以对结果执行相关的转换, 如:用atoi()把结果转换为整数(integer), 如果是二进制数据, 则可以直接强制类型转换, 如:(void*)values[i]。

程序示例:

#include <stdio.h>
#include <stdlib.h>
#include "util.h"
#pragma comment(lib, "sqlite3.lib")  

int callback(void* data, int ncols, char** values, char** headers);  

int main(int argc, char **argv)
{
    sqlite3 *db;
    int rc;
    char *sql;
    char *zErr;
    char* data;  

    rc = sqlite3_open("test.db", &db);
    if(rc)
    {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        exit(1);
    }  

    data = "Callback function called";
    sql = "insert into episodes (name, cid) values ('Mackinaw Peaches', 1);"
          "select * from episodes;";
    rc = sqlite3_exec(db, sql, callback, data, &zErr);  

    if(rc != SQLITE_OK)
    {
        if (zErr != NULL)
        {
            fprintf(stderr, "SQL error: %s\n", zErr);
            sqlite3_free(zErr);
        }
    }  

    sqlite3_close(db);  

    return 0;
}  

int callback(void* data, int ncols, char** values, char** headers)
{
    int i;
    fprintf(stdout, "%s: ", (const char*)data);
    for(i=0; i < ncols; i++)
    {
        fprintf(stdout, "%s=%s ", headers[i], values[i]);
    }  

    fprintf(stdout, "\n");
    return 0;
}  

说明:对sqlite3_exec()执行结果中查询到的每条记录调用callback()函数。

   每条记录的相应字段值存放于values数组,表头存放于headers数组,可以完成相应数据处理。

SQLite源程序分析之回叫机制的更多相关文章

  1. SQLite源程序分析之sqlite3.c

    /****************************************************************************** ** This file is an a ...

  2. 【Zookeeper】源码分析之Watcher机制(二)

    一.前言 前面已经分析了Watcher机制中的第一部分,即在org.apache.zookeeper下的相关类,接着来分析org.apache.zookeeper.server下的WatchManag ...

  3. 【Zookeeper】源码分析之Watcher机制(三)之Zookeeper

    一.前言 前面已经分析了Watcher机制中的大多数类,本篇对于ZKWatchManager的外部类Zookeeper进行分析. 二.Zookeeper源码分析 2.1 类的内部类 Zookeeper ...

  4. 【Zookeeper】源码分析之Watcher机制(二)之WatchManager

    一.前言 前面已经分析了Watcher机制中的第一部分,即在org.apache.zookeeper下的相关类,接着来分析org.apache.zookeeper.server下的WatchManag ...

  5. kernel 3.10内核源码分析--hung task机制

    kernel 3.10内核源码分析--hung task机制 一.相关知识: 长期以来,处于D状态(TASK_UNINTERRUPTIBLE状态)的进程 都是让人比较烦恼的问题,处于D状态的进程不能接 ...

  6. Android SQLite性能分析

    作为Android预置的数据库模块,对SQLite的深入理解是很有必要的,能够从中找到一些优化的方向. 这里对SQLite的性能和内存进行了一些測试分析.对照了不同操作的运行性能和内存占用的情况,粗略 ...

  7. SQLite3源程序分析之分析器的生成

    1.概述 Lemon是一个LALR(1)文法分析器生成工具,与bison和yacc类似,是一个可以独立于SQLite使用的开源的分析器生成工具.而且它使用与yacc(bison)不同的语法规则,可以减 ...

  8. SQLite3源程序分析之查询处理及优化

    前言 查询处理及优化是关系数据库得以流行的根本原因,也是关系数据库系统最核心的技术之一.SQLite的查询处理模块很精致,而且很容易移植到不支持SQL的存储引擎(Berkeley DB最新的版本已经将 ...

  9. SQLite3源程序分析之虚拟机

    前言 最早的虚拟机可追溯到IBM的VM/370,到上个世纪90年代,在计算机程序设计语言领域又出现一件革命性的事情——Java语言的出现,它与c++最大的不同在于它必须在Java虚拟机上运行.Java ...

随机推荐

  1. PHP练习题

    在PHP中,定义一个常量define(‘HoverTree’,’何问起’,true),以下语句正确输出“何问起”的是( ).   A.echo hovertree;B.echo Hover Tree; ...

  2. [WinForm] DataGridView 绑定 DT && ComboBox 列绑定 Dict

    一  需求介绍 一般像枚举类型的数据,我们在数据库里存储着诸如(1.2.3.4-)或者("001"."002"."003"-)此类,但是界面 ...

  3. Sql常用语句(3)

    --显示sql server现有的所有数据库 exec sp_helpdb --查看数据表设置的约束 exec sp_helpconstraint SubjectType --update selec ...

  4. 【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 目录索引

    索引 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目(1)搭建MVC环境 注册区域 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目(2)创建 ...

  5. C#开发微信门户及应用(10)--在管理系统中同步微信用户分组信息

    在前面几篇文章中,逐步从原有微信的API封装的基础上过渡到微信应用平台管理系统里面,逐步介绍管理系统中的微信数据的界面设计,以及相关的处理操作过程的逻辑和代码,希望从更高一个层次,向大家介绍微信的应用 ...

  6. 创建虚拟目录失败,必须为服务器名称指定“localhost”?看进来!!

    没废话,直接讲! 关于微信开发过程,远程调试后,再次打开vs出现项目加载失败的解决办法! 上图: 这图应该不陌生,你肯定打开iis把绑定的域名给干掉了.这个提示很坑人,简直就是坑爹!!!fck!! 来 ...

  7. react-echarts之折线图的显示

    react中想要实现折线图和饼图的功能,需要引入react-echarts包,然后再实现折线图的功能.我这里引用的版本是:0.1.1.其他的写法参echarts官网即可.下面详细讲解的是我在react ...

  8. DHtmlx组件获取选中行的某一列对应的值

    最近刚刚接触DHtmlx这个js组件,对它还不是太了解,还在学习中,算是记录自己学习该组件的历程吧. 首先xml文件里有一个grid,有对应的checkbox,通过 var selectedId = ...

  9. 卡巴斯基2017激活教程_卡巴斯基2017用授权文件KEY激活的方法

    原创:天诺时空 更新时间:2016-11-09   2016年9月7日,卡巴斯基2017版全新上市,卡巴斯基依旧为大家奉上满足您所有需求的安全软件产品,为不同年龄层.不同人群给予全方位保护,同时延续卡 ...

  10. x01.Tetris: 俄罗斯方块

    最强大脑有个小孩玩俄罗斯方块游戏神乎其技,那么,就写一个吧,玩玩而已. 由于逻辑简单,又作了一些简化,所以代码并不多. using System; using System.Collections.G ...