sqlite入门基础(一):sqlite3_open,sqlite3_exec,slite3_close
打开数据库链接sqlite3_open用法
原型:
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
用这个函数开始数据库操作。需要传入两个参数,一是数据库文件名,比如:E:/test.db。文件名不需要一定存在,如果此文件不存 在,sqlite会自动建立它。如果它存在,就尝试把它当数据库文件来打开。二是sqlite3**,即前面提到的关键数据结构。这个结构底层细节如何, 你不要管它。
函数返回值表示操作是否正确,如果是SQLITE_OK则表示操作正常。相关的返回值sqlite定义了一些宏。具体这些宏的含义可
以参考sqlite3.h 文件。里面有详细定义(顺便说一下,sqlite3
的代码注释率自称是非常高的,实际上也的确很高。只要你会看英文,sqlite 可以让你学到不少东西)。
关闭数据库链接sqlite3_close用法
原型:
int sqlite3_close(sqlite3 *ppDb);
ppDb为刚才使用sqlite3_open打开的数据库链接
执行sql操作sqlite3_exec用法
原型:
int sqlite3_exec(
sqlite3* ppDb, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
这就是执行一条sql 语句的函数。
第1个参数不再说了,是前面open函数得到的指针。说了是关键数据结构。
第2个参数constchar*sql是一条sql 语句,以\0结尾。
第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。
第4个参数void*是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写
法,以及这个参数的使用。
第
5个参数char** errmsg 是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行sqlite3_exec
之后,执行失败时可以查阅这个指针(直接cout<<errmsg得到一串字符串信息,这串信息告诉你错在什么地方。
sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个
char*得到具体错误提示。
说明:通常,sqlite3_callback
和它后面的void*这两个位置都可以填NULL。填NULL表示你不需要回调。比如你做insert
操作,做delete操作,就没有必要使用回调。而当你做select 时,就要使用回调,因为sqlite3
把数据查出来,得通过回调告诉你查出了什么数据。
exec 的回调
typedef int(*sqlite3_callback)(void*,int,char**,char**);
你的回调函数必须定义成上面这个函数的类型。下面给个简单的例子:
//sqlite3的回调函数
//sqlite 每查到一条记录,就调用一次这个回调
int LoadMyInfo(void* para,intn_column,char** column_value,char** column_name);
//para是你在sqlite3_exec 里传入的void*参数通过para参数,你可以传入一些特殊的指针(比如类指针、结构指针),
//然后在这里面强制转换成对应的类型(这里面是void*类型,必须强制转换成你的类型才可用)。然后操作这些数据
//n_column是这一条记录有多少个字段(即这条记录有多少列)
//char** column_value 是个关键值,查出来的数据都保存在这里,它实际上是个1维数组(不要以为是2维数组),
//每一个元素都是一个char*值,是一个字段内容(用字符串来表示,以\0结尾)
//char** column_name 跟column_value是对应的,表示这个字段的字段名称
实例:
#include <iostream>
using namespace std;
#include "sqlite/sqlite3.h"
int callback(void*,int,char**,char**);
int main()
{
sqlite3* db;
int nResult = sqlite3_open("test.db",&db);
if (nResult != SQLITE_OK)
{
cout<<"打开数据库失败:"<<sqlite3_errmsg(db)<<endl;
return ;
}
else
{
cout<<"数据库打开成功"<<endl;
} char* errmsg; nResult = sqlite3_exec(db,"create table fuck(id integer primary key autoincrement,name varchar(100))",NULL,NULL,&errmsg);
if (nResult != SQLITE_OK)
{
sqlite3_close(db);
cout<<errmsg;
sqlite3_free(errmsg);
return ;
}
string strSql;
strSql+="begin;\n";
for (int i=;i<;i++)
{
strSql+="insert into fuck values(null,'heh');\n";
}
strSql+="commit;";
//cout<<strSql<<endl; nResult = sqlite3_exec(db,strSql.c_str(),NULL,NULL,&errmsg); if (nResult != SQLITE_OK)
{
sqlite3_close(db);
cout<<errmsg<<endl;
sqlite3_free(errmsg);
return ;
} strSql = "select * from fuck";
nResult = sqlite3_exec(db,strSql.c_str(),callback,NULL,&errmsg);
if (nResult != SQLITE_OK)
{
sqlite3_close(db);
cout<<errmsg<<endl;
sqlite3_free(errmsg);
return ;
} sqlite3_close(db);
return ;
} int callback(void* ,int nCount,char** pValue,char** pName)
{
string s;
for(int i=;i<nCount;i++)
{
s+=pName[i];
s+=":";
s+=pValue[i];
s+="\n";
}
cout<<s<<endl;
return ;
} sqlite3_exec是sqlite3_prepare_v2,sqlite3_step()和sqlite3_finalize()的封装,能让程序多次执行sql语句而不要写许多重复的代码。
sqlite入门基础(一):sqlite3_open,sqlite3_exec,slite3_close的更多相关文章
- sqlite3入门之sqlite3_open,sqlite3_exec,slite3_close
sqlite3_open sqlite3_open函数原型: int sqlite3_open( const char *filename, /* Database filename (UTF-8) ...
- 数据库(SQLITE3函数总结): sqlite3_open, sqlite3_exec, slite3_close,sqlite3_prepare_v2,sqlite3_column_text,
Sqlite3 的确非常好用.小巧.速度快.近期研究它,有一些收获,这里把我对 sqlite3 的研究列出来,以备忘记. 导入SQLLite library并引入头文件. libsqlite3.dyl ...
- SQLite入门与分析(二)---设计与概念(续)
SQLite入门与分析(二)---设计与概念(续) 写在前面:本节讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家因在数据库领域的成就而获ACM图灵奖,而其中之一Jim G ...
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...
- SQLite入门语句之HAVING和DISTINCT
一.SQLite入门语句之HAVING HAVING 子句允许指定条件来过滤将出现在最终结果中的分组结果. WHERE 子句在所选列上设置条件,而 HAVING 子句则在由 GROUP BY 子句创建 ...
- 01shell入门基础
01shell入门基础 为什么学习和使用shell编程 shell是一种脚本语言,脚本语言是相对于编译语言而言的.脚本语言不需要编译,由解释器读取程序并且执行其中的语句,而编译语言需要编译成可执行代码 ...
- Markdown入门基础
// Markdown入门基础 最近准备开始强迫自己写博文,以治疗严重的拖延症,再不治疗就“病入骨髓,司命之所属,无奈何”了啊.正所谓“工欲善其事,必先利其器”,于是乎在写博文前,博主特地研究了下博文 ...
- JavaScript入门基础
JavaScript基本语法 1.运算符 运算符就是完成操作的一系列符号,它有七类: 赋值运算符(=,+=,-=,*=,/=,%=,<<=,>>=,|=,&=).算术运 ...
- C++ STL编程轻松入门基础
C++ STL编程轻松入门基础 1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL 1.2 追根溯源:STL的历史 1.3 千丝万缕的联系 1.4 STL的不同实现版本 2 牛刀小试 ...
随机推荐
- 在Eclipse中查看JDK源码的方法
遇到这个问题是因为想证明Vector中的get()方法是不是用synchronized关键字修饰的来保证线程安全的方法, 于是在Eclipse里面: Vector<Integer> vec ...
- Head First设计模式之外观模式
一.定义 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使用. 外观模式不只是简化了接口,也将客户从组件的子系统中解耦. 外观和适配器可以包装许多类, ...
- Netty入门之客户端与服务端通信(二)
Netty入门之客户端与服务端通信(二) 一.简介 在上一篇博文中笔者写了关于Netty入门级的Hello World程序.书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码 ...
- 如何把kotlin+spring boot开发的项目部署在tomcat上
本文只讲部署过程,你首先要保证你的程序能在IDE里跑起来: 先看看你的application.properties中设置的端口号与你服务器上tomcat的端口号是否一致 server.port=80 ...
- File System 之本地文件系统
上一篇文章提到了,最近做一个基于 File System/IndexedDB的应用,上一篇是定额和使用的查询. 因为LocalFileSystem只有chrome支持,有点尴尬,如果按需加载又何来尴尬 ...
- webapi 异步返回
两年前我遇到一个难题: https://q.cnblogs.com/q/78177 WebAPI中使用socket如果在server端回复了再返回值? 现在终于做出一种实现了: [HttpGet] ...
- MySQL多Text字段报8126错误(解决过程)
一.背景 我们的MySQL数据库有一张10个Text的字段的表,还包括几个char和varchar字段,由于业务需求,我在表中加多一个Text字段的时候,插入记录的出现了下面的错误: Row size ...
- visualSVN 版本控制
用SmartSVN提交代码的时候提示:svn: File has inconsistent newlines 这是由于要提交的文件编码时混合了windows和unix符号导致的. 解决方法: Proj ...
- C#学习笔记-适配器模式
什么是适配器模式? 适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 什么时候运用适配器模式? ...
- 基于input子系统的sensor驱动调试(一)
要想弄明白世界的本质,就要追根溯源:代码也是一样的道理: 最近调试几个sensor驱动,alps sensor驱动.compass sensor驱动.G-sensor驱动都是一样的架构: 一.基于in ...