SQLite3源程序分析

回调函数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数组,可以完成相应数据处理。

 
时间: 2024-08-27 18:40:45

SQLite3源程序分析的相关文章

SQLite3源程序分析之Lemon分析器生成工具

1.概述 Lemon是一个LALR(1)文法分析器生成工具.虽然它是SQLite作者针对SQLite写的一个分析器生成工具,但是它与bison和yacc类似,是一个可以独立于SQLite使用的开源的分析器生成工具.而且它使用与yacc(bison)不同的语法规则,可以减少编程时出现错误的机会.Lemon比yacc和bison更精致.更快,而且是可重入的,也是线程安全的——这对于支持多线程的程序是非常重要的. Lemon的主要功能就是根据上下文无关文法(CFG),生成支持该文法的分析器.程序的输入

LCC编译器的源程序分析 1 C编译器的目标

先从简单的目标来分析这个大规模的C编译器,毕竟它的功能比较复杂,并且源程序的行数也是非常多的.因此,把简单的目标定出来,然后再分析它,这样才会有的放矢.接着再跟着编译运行的主线来分析它的源程序.下面先看一下简单的C例子,如下: #001 #include <stdio.h> #002 #003 int main(void) #004 { #005  int nTest1 = 1; #006  int nTest2 = 2; #007  int nTest3; #008  int i; #009

SQLite源程序分析之回叫机制

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.

&lt;01&gt;主函数分析+创建一个新的Target+C语言程序执行流程

1.C语言的源程序的后缀:.c格式 2.C语言源程序: 1)由函数构成 2)在一个程序中,只有一个主函数(主函数由系统调用) 3)函数只有被调用的时候,才执行 4)如果没有主函数程序无法运行 5) C语言中语句结束一定要有分号 3.主函数的写法: int main(){ printf("hello world"); return 0; } 4.C语言程序的执行 1)command+r 2)点击左上角的 三角 符号 //Program ended with exit code: 0  程

Android学习路线

第一阶段:Java面向对象编程 1.Java基本数据类型与表达式,分支循环. 2.String和StringBuffer的使用.正则表达式. 3.面向对象的抽象,封装,继承,多态,类与对象,对象初始化和回收:构造函数.this关键字.方法和方法的参数传递过程.static关键字.内部类,Java的垃极回收机制,Javadoc介绍. 4.对象实例化过程.方法的覆盖.final关键字.抽象类.接口.继承的优点和缺点剖析:对象的多态性:子类和父类之间的转换.抽象类和接口在多态中的应用.多态带来的好处.

编译 &amp; 预处理

编译(compilation , compile) 1.利用编译程序从源语言编写的源程序产生目标程序的过程. 2.用编译程序产生目标程序的动作. 编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译程序把人们熟悉的语言换成2进制的. 编译程序把一个源程序翻译成目标程序的工作过程分为五个阶段:词法分析:语法分析:语义检查和中间代码生成:代码优化:目标代码生成.主要是进行词法分析和语法分析,又称为源程序分析,分析过程中发现有语法错误,给出提示信息. 预处理(pre-treatm

android开发的学习路线

android开发的学习路线 第一阶段:Java面向对象编程1.Java基本数据类型与表达 式,分支循环. 2.String和StringBuffer的使用.正则表达式. 3.面向对象的抽象,封装,继承,多态,类与对象,对象初始化和回 收:构造函数.this关键字.方法和方法的参数传递过程.static关键字.内部类,Java的垃极回收机制,Javadoc介绍. 4.对象实例化 过程.方法的覆盖.final关键字.抽象类.接口.继承的优点和缺点剖析:对象的多态性:子类和父类之间的转换.抽象类和接

【路线篇(二)】知识点归纳

[喵"的Android之路][路线篇(二)]知识点归纳 参考:http://blog.csdn.net/xujing81/article/details/7313507 第一阶段:Java面向对象编程 1 Java数据类型与运算符 2 String和StringBuffer的使用.正则表达式 3 我给面向对象的抽象,封装,继承,多态,类与对象,对象初始化和回收:构造函数.this关键字.方法和方法的参数传递过程.static关键字.内部类,Java的垃极回收机制,Javadoc介绍 4 对象实例

1.预处理器,编译器,汇编器和链接器

摘自http://www.cnblogs.com/maomaohhmm/archive/2012/10/28/2743903.html 1.预处理器,编译器,汇编器和链接器 (1).预处理(cpp):预处理器不止一种,而C/C++的预处理器就是其中最低端的一种——词法预处理器,主要是进行文本替换.宏展开.删除注释这类简单工作. gcc -E 选项可以得到预处理后的结果,扩展名为.i: C/C++预处理不做任何语法检查,不仅是因为它不具备语法检查功能,也因为预处理命令不属于C/C++语句(这也是定