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.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源程序分析之回叫机制的更多相关文章
- SQLite源程序分析之sqlite3.c
/****************************************************************************** ** This file is an a ...
- 【Zookeeper】源码分析之Watcher机制(二)
一.前言 前面已经分析了Watcher机制中的第一部分,即在org.apache.zookeeper下的相关类,接着来分析org.apache.zookeeper.server下的WatchManag ...
- 【Zookeeper】源码分析之Watcher机制(三)之Zookeeper
一.前言 前面已经分析了Watcher机制中的大多数类,本篇对于ZKWatchManager的外部类Zookeeper进行分析. 二.Zookeeper源码分析 2.1 类的内部类 Zookeeper ...
- 【Zookeeper】源码分析之Watcher机制(二)之WatchManager
一.前言 前面已经分析了Watcher机制中的第一部分,即在org.apache.zookeeper下的相关类,接着来分析org.apache.zookeeper.server下的WatchManag ...
- kernel 3.10内核源码分析--hung task机制
kernel 3.10内核源码分析--hung task机制 一.相关知识: 长期以来,处于D状态(TASK_UNINTERRUPTIBLE状态)的进程 都是让人比较烦恼的问题,处于D状态的进程不能接 ...
- Android SQLite性能分析
作为Android预置的数据库模块,对SQLite的深入理解是很有必要的,能够从中找到一些优化的方向. 这里对SQLite的性能和内存进行了一些測试分析.对照了不同操作的运行性能和内存占用的情况,粗略 ...
- SQLite3源程序分析之分析器的生成
1.概述 Lemon是一个LALR(1)文法分析器生成工具,与bison和yacc类似,是一个可以独立于SQLite使用的开源的分析器生成工具.而且它使用与yacc(bison)不同的语法规则,可以减 ...
- SQLite3源程序分析之查询处理及优化
前言 查询处理及优化是关系数据库得以流行的根本原因,也是关系数据库系统最核心的技术之一.SQLite的查询处理模块很精致,而且很容易移植到不支持SQL的存储引擎(Berkeley DB最新的版本已经将 ...
- SQLite3源程序分析之虚拟机
前言 最早的虚拟机可追溯到IBM的VM/370,到上个世纪90年代,在计算机程序设计语言领域又出现一件革命性的事情——Java语言的出现,它与c++最大的不同在于它必须在Java虚拟机上运行.Java ...
随机推荐
- 在真机调试 iOS 应用:理解 Certificates, Identifiers & Profiles
No matching provisioning profiles found. No matching code signing identity found. Your account alrea ...
- 基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)
今天没有延续上一篇讲的内容,穿插一段小插曲,WebSocket 实时数据通讯同步的问题,今天我们并不是很纯粹地讲 WebSocket 相关知识,我们通过 WebGL 3D 拓扑图来呈现一个有趣的 De ...
- linux终端指令总结
一直没机会进行linux指令的系统学习,但是工作中总能遇到通过指令操作文件或数据库的情况,总不能一味地依赖后端开发者的帮忙.上任领导说过,要是在同一个地方跌倒,那么你就是傻子.我可不想成为傻子,so, ...
- 设计模式(六)原型模式(Prototype Pattern)
一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...
- Redis(li)
一.Redis基础介绍 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset ...
- WCF入门教程3——WCF通信模式
本章内容 请求/响应模式 单工模式 双工模式 WCF异步调用 请求与响应模式 请求/响应 请求/响应通信是指客户端向服务端发送消息后,服务端会向客户端发送响应.这也意味着在接收到服务的响应以前 ...
- RPC是什么?科普一下
RPC概念及分类 RPC全称为Remote Procedure Call,翻译过来为“远程过程调用”.目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用 ...
- 初探React,将我们的View标签化
前言 我之前喜欢玩一款游戏:全民飞机大战,而且有点痴迷其中,如果你想站在游戏的第一阶梯,便需要不断的练技术练装备,但是腾讯的游戏一般而言是有点恶心的,他会不断的出新飞机.新装备.新宠物,所以,很多时候 ...
- 【centos7】添加开机启动服务/脚本
一.添加开机自启服务 在centos7中添加开机自启服务非常方便,只需要两条命令(以Jenkins为例): systemctl enable jenkins.service #设置jenkins服务为 ...
- ipad和iphone的适配
关于xib或者storybord下iphone的横竖屏的适配以及ipad的适配 ios8出现了Size Classes,解决了各种屏幕适配的问题,他把屏幕的宽和高分别分成了三种,把屏幕总共分成了九种情 ...