开始简单的C/C++调用SQLite

每到期末,总是有一门课程设计。

这次的比较蛋疼,是 软件工程 的课程设计。

软件工程,写代码对我来说压力不大。

问题是 软件工程 这门课,就是研究软件的构建的,也就是说,鹚最讨厌写的那些什么 “市场分析、开发计划、数据字典、数据流图、精化阶段……”。

文档的编写是鹚一直觉得蛋疼的事情,而且这次还必须做的有模有样,鹚除了画点程序流程图,程序功能什么的,其他的都觉得是多余的东西……

嗯嗯,都是群组合作嘛,蛋疼的事情还有同伴去做嘛-_-

这次的题目是 “网吧管理系统”。

网吧大家去过,什么会员,普通会员,每个人的账户余额,每个人何时上机,何时下机,用户的资料储存在那里等等。

当然,我们无法写出完美的系统,所以,作为课程设计,我们还是会尽最大努力将其模拟出来。

鹚是理想主义,于是开始yy架构。

当然,最真实的模拟方案,就是使用 CS(客户端/服务器)方式。

可是组长发话了:“你想设计成CS模式是吧,但是这样难度很大,我们先不要考虑客户端好不好。”

“额,也是啊,要不建两个线程,一个模拟服务器,一个模拟客户端吖。”(此想法纯属yy,请勿在意

“嗯,只要能实现,也是好办法”。

“额,算了数据什么的,到时候还是直接对整个数据进行扫描吧,这样是最简单稳妥的实现方案了,只是效率低下,课程设计,以目前的水平,也只能这样啦。”

虽然鹚也不甘心,但是线程什么的,就算我写的出来,我也只在 Linux 下实现过,而每次课程设计,为了和同学保持一致,我又得回到 Windows 下操起古老的 VC6.0 。

但是鹚也不会放弃尝试新的东西,虽然不知道最终能不能用得上。

组长问我:“你会数据库嘛,这样我们看起来会屌一些?不过不行的话,用文件实现也是可以的。”

额,虽然日日用着 Mysql 的Wordpress,但真正SQL起来,还远远不行。

但是,有什么不行的呢,有什么不会的呢,只要我敢去做!

“嗯,我试试看!”

马上考虑用什么实现数据操作好一点,Mysql?貌似太庞大,老湿也不会认帐……XML?这个虽然方便数据操作,但貌似也不叫数据库啊……

嗯嗯,想到最后,就用小巧而强大的 Sqlite3 来实现吧。

马上去 http://www.sqlite.org/ 下载了源码。

因为我要用 C/C++来实现 对 Sqlite 的操作,所以需要以下文件。

sqlite3.def    //用来生成 sqlite3.lib 的链接库

sqlite3.h //sqlite的函数库

sqlite3.dll    //sqlite的运行库

先生成 sqlite3.lib 吧:

将 sqlite3.def copy 到 D:\Program Files\Microsoft Visual Studio\VC98\Bin

从 D:\Program Files\Microsoft Visual Studio\ Common\MSDev98\Bin 复制  MSPDB60.DLL 到 D:\Program Files\Microsoft Visual Studio\VC98\Bin 目录下。

打开 CMD cd 到 D:\Program Files\Microsoft Visual Studio\VC98\Bin

输入命令 LIB /MACHINE:IX86 /DEF:sqlite3.def 就生成了 sqlite3.lib 。

接下来建立一个 windows32 console application 的工程。

复制 sqlite3.h sqlite3.lib sqlite3.dll 到工程目录。

源代码的头与库引用记得这样写:

#include "sqlite3.h" //引入sqlite3头文件
#pragma comment(lib,"sqlite3.lib")	//绑定sqlite3连接库

以下为鹚用 纯C 实现的 SQL 操作,当然不管是 Sqlite ,还是Mysql,都是支持 CREAT TABLE ,SELECT *…… 这样的工业标准的。

#include 
#include 
#include 
#include "sqlite3.h" //引入sqlite3头文件
#pragma comment(lib,"sqlite3.lib")	//绑定sqlite3连接库
using namespace std;

int sqlitedbcreat()
{
	sqlite3 *conn;
	char *errormsg;
	char notice;
	char sqlname[20];
	getchar();
	printf("需要建立一个新的数据库嘛?(Y/N):");
	scanf("%c",¬ice);
	printf("#####################################\n");
	if(notice=='n') 
	{
		printf("Nothing Have Done\n");
		printf("###################\n\n");
		return 0;
	}
	printf("输入数据库名称: ");
	getchar();
	gets(sqlname);
	if(SQLITE_OK!=sqlite3_open(sqlname,&conn))
	{
		printf("数据库 %s 创建失败: %s",sqlname,errormsg);
		exit(-1);
	}
	else printf("数据库 %s 创建成功 ^_^ \n",sqlname);
	if(SQLITE_OK!=sqlite3_close(conn))
	{
		printf("到数据库 %s 的连接无法断开 -_- \n",sqlname);
	}
	else printf("到数据库 %s 的连接已经断开! \n",sqlname);
	printf("######################\n\n");
	return 0;
}

int sqlitetablecreat()
{
	sqlite3 *conn;
	char sql[200];
	char *errormsg;
	char notice;
	char sqlname[20];
	char tablename[20]="default";
	getchar();
	printf("输入你想打开数据库名称: ");
	gets(sqlname);
	printf("需要在数据库 %s 中建立一个新的数据表嘛?(Y/N):",sqlname);
	scanf("%c",¬ice);
	printf("#####################################\n");
	if(notice=='n') 
	{
		printf("Nothing Have Done\n");
		printf("###################\n\n");
		return 0;
	}
	if(SQLITE_OK!=sqlite3_open(sqlname,&conn))
	{
		printf("数据库 %s 连接失败: %s",sqlname,errormsg);
		exit(-1);
	}
	else printf("数据库 %s 连接成功 ^_^ \n",sqlname);
	printf("输入你想创建的表的名称: ");
	getchar();
	gets(tablename);
	sprintf(sql," CREATE TABLE [%s] ( [id] int, [name] char(20), [age] int )",tablename);
	if(SQLITE_OK!=sqlite3_exec(conn,sql,0,0,&errormsg))
	{
		printf("数据表 %s 创建失败: %s\n",tablename,errormsg);
		exit (-1);
	}
	else printf("数据表 %s 创建成功^_^\n",tablename);
	if(SQLITE_OK!=sqlite3_close(conn))
	{
		printf("到数据库 %s 的连接无法断开 -_- \n",sqlname);
	}
	else printf("到数据库 %s 的连接已经断开! \n",sqlname);
	printf("#########################\n\n");
	return 0;
}

int sqlitetableinsert()
{
	sqlite3 *conn;
	char sql[200];
	char *errormsg;
	int i;
	char notice;
	char sqlname[20];
	char tablename[20]="default";
	getchar();
	printf("输入你想打开数据库名称: ");
	gets(sqlname);
	printf("需要插入新的数据嘛?(Y/N):");
	scanf("%c",¬ice);
	printf("#####################################\n");
	if(notice=='n') 
	{
		printf("Nothing Have Done\n");
		printf("###################\n\n");
		return 0;
	}
	if(SQLITE_OK!=sqlite3_open(sqlname,&conn))
	{
		printf("数据库 %s 连接失败: %s",sqlname,errormsg);
		exit(-1);
	}
	else printf("数据库 %s 连接成功 ^_^ \n",sqlname);
	printf("输入你想插入数据的表的名称: ");
	getchar();
	gets(tablename);
	for(i=0;i<10;i++)
	{
		sprintf(sql," INSERT INTO [%s] ( [id], [name], [age] ) VALUES (%d,'%s',%d) ",tablename, i, "Mucid", i);
		if(SQLITE_OK!=sqlite3_exec(conn,sql,0,0,&errormsg))
		{
			printf("记录 %d 插入表单 %s 失败 -_- 错误: %s \n",i,tablename,errormsg);
		}
		else printf("记录 %d 插入表单 %s 成功 \n",i,tablename);
	}
	if(SQLITE_OK!=sqlite3_close(conn))
	{
		printf("到数据库 %s 的连接无法断开 -_- \n",sqlname);
	}
	else printf("到数据库 %s 的连接已经断开! \n",sqlname);
	printf("#############################\n\n");
	return 0;
}

int sqlitecallbackprintf(void *data,int ncolumnsm,char **colvalues,char **colnames)
{
	int i;
	for(i=0;i

Sqlite3 的接口函数,鹚算是基本掌握,目前可以实现建立数据库,在数据库中建立表,往表中插入数据,查询么数据库么表中的数据等。

所以,接下的重心,主要是对 SQL 语句的熟悉,并将其包装到函数中,实现完整功能。

鹚在努力的将 sqllite 包装起来,做出一个小“引擎”,然后方便给伙伴们调用,这样即使他们不懂数据库也没关系。

当然实在无法实现与伙伴们融合的话,回过头来直接用 “文件” 来储存数据的话,也是很方便的。

毕竟,鹚这是在自我挑战,不光是为了神马课程设计。

以上的代码中,让鹚体验到了两个强大的东东。

一是 sprintf() 这个函数,他可以将 SQL 语句 格式化到一个字符数组中,然后传入 sqlite3_exec() 函数中,比直接 SQL 要温柔,灵活许多。

第二个是,鹚第一次使用了 回调 函数,用来返回 SQL 查询的结果。当然,这花了鹚一些时间来揣摩 回调 这个概念,多亏了 IBM 的一篇文档,写的很清晰。

当然,你不习惯 纯C 的实现的话,你可以轻易的将以上 Code 改装成 C++ 的方式:

1. 将所有的 函数包装到一个类中。

2. sprintf() 这个函数,应该可以用 C++ istrstream 字符串 流来实现,但是就算你用 C++ 也是可以使用 sprintf() 这个函数的,毕竟,C与C++天生就是可以完美的融合在一起的说!

只是鹚觉得嘛,既然 Sqlite 也是用 C 写的,那么直接用 纯C 实现,貌似更加原汁原味的说!

对了程序运行结果如下:

About Mucid

My life is brilliant !
This entry was posted in Technology and tagged , , , , , . Bookmark the permalink.

403 Responses to 开始简单的C/C++调用SQLite

  1. louis vuitton outlet says: Internet Explorer 6.0 Internet Explorer 6.0 Windows XP Windows XP

    It’s a good post.

  2. christian louboutin says: Internet Explorer 6.0 Internet Explorer 6.0 Windows XP Windows XP

    It’s a good post.