SQLite C/C++

http://blog.csdn.net/diaoser/article/details/6830786

 

辅助工具工具

Sqlite数据库的管理工具有SQLiteManager、SqliteAdmin等。

SqliteManager只有英文版,但功能强大,有个问题就是不支持ANSI字符集的汉字显示。其自带的帮助文档有SQL语句的详细介绍,对于不熟悉Sql语句的人来说很方便。而且它的很多操作都有自动的SQL语句提示,对于不常使用数据库的人来说也很好用。

SqliteAdmin有绿色中文版,功能相对于SqliteManager略少,对于熟悉Sql语句的人,该版本够用了。

C/C++使用前准备

直接将sqlite3.h和sqlite3.c加入自己的C/C++工程中,即可使用sqlite3。

打开关闭数据库

Sqlite支持UTF-8和UTF-16,不过它居然不支持C/C++程序中最常用的ANSI。因此数据库路径中如果包含中文字符的话,需要将路径转换成相应的字符格式。

1、以UTF-8方式打开

//打开数据库

sqlite3 *db = NULL;

int result = sqlite3_open("c:\\abc.db", &db);

if (SQLITE_OK != result)

{

return;

}

//关闭数据库

sqlite3_close(db);

2、以UTF-16方式打开

如要以UTF-16方式打开,把打开数据库的语句改为"sqlite3_open16(L"c:\\abc.db", &db)"即可。

但一般情况,强烈不建议使用UTF-16方式打开数据库, 根据我的测试,我发现如果以这种方式打开数据库,在后续创建数据表的时候,如果其中有某项为TEXT类型。那么数据表的这项数据内容,将会强制确定类型为 UTF-16。也就是说,你插入的任何数据,都将被转换为UTF-16并存入数据库。而执行SQL的语句是UTF-8格式的,因此当你取出的数据和你存入 的数据是不一致的,很显然这对于使用者而言是一个灾难。

执行SQL语句

执行SQL语句可以调用sqlite3_exec函数,一般来说,如果不需要返回的数据和错误信息,执行方式如下:

sqlite3_exec(db, strSQL, 0, 0, 0);

1、创建表

假设创建如下图所示的数据库:

其SQL语句为:

CREATE TABLE [MyTable] ([ID] INTEGER PRIMARY KEY NOT NULL,[MyText] TEXT NULL, [MyDate]DATE NOT NULL, [MyTime] TIME NULL,[MyFloat] FLOAT NULL)

2、插入记录

下面是插入一条记录的示例SQL语句。

INSERT INTO MyTable (MyText, MyDate, MyTime, MyFloat) VALUES ('---上班好远!', '2012-03-23', '9:00:00', 1000)

3、更新记录

下面是更新若干条记录的示例SQL语句。

UPDATE MyTable SET MyText='真的吗?', MyTime='10:00:00' WHERE ID >=0 AND ID <=20

4、删除记录

下面是删除若干条记录的示例SQL语句。

DELETE FROM MyTable WHERE ID >=3 AND ID <=5

5、批量操作

如果要进行大量的操作,比如要插入10000条数据,如果逐条执行SQL语句,则消耗的时间非常长。采用事务的方式批量处理,可以极大程度提升操作速度(我用1000条记录实验了一下,速度提高了500倍以上)。

下面是一个批量插入10000条数据的代码示例:

//插入条数据(在Begin和Commit之间批量操作,可以大幅度提高效率)

result = sqlite3_exec(db, "BEGIN;", 0, 0, 0);

for (int i=0; i<10000; i++)

{

//插入一条数据

result = sqlite3_exec(db,

"INSERT INTO MyTable (MyText, MyDate, MyTime, MyFloat) VALUES ('---上班好远!', '2012-03-23', '9:00:00', 1000);",

0, 0, 0);

}

result = sqlite3_exec(db, "COMMIT;", 0, 0, 0);

 
查询并返回结果 
 
1、以表单形式返回

下面是以表单形式获取数据的示例代码:

//查询记录(返回数据表的方式)

char **pazResult;

int nRow, nCol;

sqlite3_get_table(db, "SELECT * FROM MyTable LIMIT 1000 OFFSET 2000", &pazResult, &nRow, &nCol, 0);

//nRow指示出有多少行

//nCol指示出有多少列

//从pazResult中可以解析出所有记录,记录以字符串形式返回

//第n列的名称,存放于pazResult[n]

//第n行第m列的数据,存放与paszResult[(m + 1) * nCol + m]

//使用完后,务必释放为记录分配的内存

sqlite3_free_table(pazResult);

上面的查询代码,也演示了如何查询指定位置指定条数的记录,这种查询方法在记录集非常庞大的时候很有用。

2、以回调形式返回

下面以代码形式示例如何获得查询语句返回的记录。

首先需要定义一个回调函数如下(参数意义待会再说):

int Result(void* pContext, int nCol, char** azValue, char**azName);

然后调用sqlite函数执行查询语句,在回调函数一栏输入上面定义的回调函数:

sqlite3_exec(db, "SELECT * FROM MyTable LIMIT 10 OFFSET 20",Result, 0, 0);

执行该SQL语句时,每返回一条记录都会触发一次上面的回调函数,在该回调函数的实现中,即可得到查询结果。

在上面的Result函数中,各个参数意义如下:

pContext

这个参数是调用sqlite3_exec函数是输入的第4个参数。它通常作为环境变量用于指示出当前执行代码的主体。示例代码中我忽略了这个参数,但正式使用时一般不会忽略它。

nCol

表示该条记录有多少列。

azValue

返回的数据都蕴含在该变量中,它也是一个字符串数组。azValue[n]即为第n列的数据。

azName

存放列的名称,azName[n]就是第n列的名称。

八、存取二进制数据

存取二进制数据需要用到sqlite3_bind_blob等函数,具体用法可以查看这些函数的声明。作为一个轻量级数据库,我一般不用它存储二进制数据,因此这儿不再详细描述这些内容。

[转]SQLite C/C++的更多相关文章

  1. 【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】

    由于个人研究需要,需要采集天气历史数据,前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),介绍了基本的采集思路和核心代码,经过1个星期的采集,历史数据库 ...

  2. UWP开发之ORM实践:如何使用Entity Framework Core做SQLite数据持久层?

    选择SQLite的理由 在做UWP开发的时候我们首选的本地数据库一般都是Sqlite,我以前也不知道为啥?后来仔细研究了一下也是有原因的: 1,微软做的UWP应用大部分也是用Sqlite.或者说是微软 ...

  3. 深入解析Sqlite的完美替代者,android数据库新王者——Realm

    写在前面: 又到一年一度七夕虐狗节,看着大家忍受着各种朋友圈和QQ空间还有现实生活中的轮番轰炸,我实在不忍心再在这里给大家补刀,所以我觉得今天不虐狗,继续给大家分享有用的. 如果你比较关心androi ...

  4. VS15 preview 5打开文件夹自动生成slnx.VC.db SQLite库疑惑?求解答

    用VS15 preview 5打开文件夹(详情查看博客http://www.cnblogs.com/zsy/p/5962242.html中配置),文件夹下多一个slnx.VC.db文件,如下图: 本文 ...

  5. Android之SQLite数据存储

    一.SQLite保存数据介绍 将数据库保存在数据库对于重复或者结构化数据(比如契约信息)而言是理想之选.SQL数据库的主要原则之一是架构:数据库如何组织正式声明.架构体现于用于创建数据库的SQL语句. ...

  6. 【教程】SQLite数据库修复

    SQLite 大家都知道,就不多说了. 有时候数据量大了,或者存储过程中出现异常,数据库就可能会出问题. 这是以前公司产品出现过的问题,导致软件都打不开了,我花了不少时间才解决的,趁现在有空贡献出来. ...

  7. SQLite学习笔记(十)&&加密

    随着移动互联网的发展,手机使用越来越广泛,sqlite作为手机端存储的一种解决方案,使用也非常普遍.但是sqlite本身安全特性却比较弱,比如不支持用户权限,只要能获取到数据库文件就能进行访问:另外也 ...

  8. mono for android中使用dapper或petapoco对sqlite进行数据操作

    在mono for android中使用dapper或petapoco,很简单,新建android 类库项目,直接把原来的文件复制过来,对Connection连接报错部分进行注释和修改就可以运行了.( ...

  9. 【腾讯Bugly干货分享】微信iOS SQLite源码优化实践

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b58022433221be01499480 作者:张三华 前言 随着微信iO ...

  10. 【腾讯Bugly干货分享】移动客户端中高效使用SQLite

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b57f2a0703f7d31b9a3932 作者:赵丰 导语 iOS 程序能 ...

随机推荐

  1. 数据库索引<二> 补充前篇

    你要准备的软件有: 最新版 Rsync for windows 服务端:cwRsync_Server_2.1.5_Installer.zip 客户端:cwRsync_2.1.5_Installer.z ...

  2. Extjs 视频教程

    ---恢复内容开始--- 网易云课堂 <尚学堂_Ext视频教程> login.html <html> <head> <meta http-equiv=&quo ...

  3. Bag of mice(CodeForces 148D )

    D. Bag of mice time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  4. Dapper使用

    公司的项目使用了Dapper做数据库连接处理,感觉不错,自己研究一下怎么用. 在网上找了找资料对Dapper都比较推崇.主要是两个方面,一个是连接速度很快,一个是代码开源且简单,只有一个SqlMapp ...

  5. SSH由WAS/Tomcat/Weblogic迁移到JBOSS

    又是一个凌晨,又一次搞项目在新的中间件上的可部署性验证... 原来将项目部署到was7上,花了三个晚上到凌晨1点多的时间,总结出了只要将common-logging和wodenxx.jar两个jar包 ...

  6. ANGULAR JS PROMISE使用

    Promise是一种模式,以同步操作的流程形式来操作异步事件,避免了层层嵌套,可以链式操作异步事件. 我们知道,在编写javascript异步代码时,callback是最最简单的机制,可是用这种机制的 ...

  7. 如何获得bin/Debug目录的路径?

    这个可以使用下面的方法 答案:bin目录:通过应用程序集合AppDomain.CurrentDomain.BaseDirectory:带有"\"System.Environment ...

  8. 简单分析Java的HashMap.entrySet()的实现

    关于Java的HashMap.entrySet(),文档是这样描述的:这个方法返回一个Set,这个Set是HashMap的视图,对Map的操作会在Set上反映出来,反过来也是.原文是 Returns ...

  9. su和su -和sudo

    1.su和sudo没有切换工作目录和环境变量,只是赋予用户权限, 而su -是真正切换到root登录,工作目录切换到/root,环境变量也同时改变. [root@oc3408554812 home]# ...

  10. 如何理解java中的变量和常量

    int a =10;这是一个变量,在后面的代码中你可以去更改a的值但如果你在声明a的时候加上了final,那么a就成了常量,后面的代码是不允许对a做修改的.还有一点你要注意,被final修饰的常量必须 ...