MFC ListControl与SQLite(二)用C++读SQLite

前文传送门
MFC ListControl与SQLite(一)SQLite的使用

SQLite数据表格读取

  1. 打开数据库文件
int sqlite3_open(const char *filename, sqlite3 **ppDb);

filename要求是用UTF-8的编码格式,但如果是文件名没有非中文字符可以忽略这个要求,用GB2312也没关系

ppDb要求传入一个sqlite3数据库的句柄指针

  1. 读取数据库表格(非回调方式查询)
int sqlite3_get_table(
  sqlite3 *db,          //打开数据库时得到的数据库指针
  const char *zSql,     //传递SQL语句,用于告诉数据库需要做什么
  char ***pazResult,    //查询到数据结果,以顺序排列的方式保存数据,类似于一维数组的保存方式
  int *pnRow,           //查询到有多少行
  int *pnColumn,        //查询到有多少列
  char **pzErrmsg       //如果方法执行失败,将错误信息反馈出来
);
  1. 释放保存表格数据的数组指针内存
void sqlite3_free_table(char **result);
  1. 关闭数据库
int sqlite3_close(sqlite3 *ppDb);

实例:

#include "sqlite3.h"  //这两个是必须要的文件,而且得自己去找,一般编译器不会自带这个
#pragma comment(lib,"sqlite3.lib")  //有挺多大佬都分享了这个资源的,我就不分享

CString(*DataBaseFile::ReadFile())[6]  //返回一个一维数组指针,数据指针保存了表格数据
{
	CString t_str, (*r_t_str)[6] = new CString[255][6];  
	//建立一个数组指针,并初始化一个地址
	//地址类型为CString,大小为可存放255行,每行6个数据的内存
	//为啥加个括号,这就是创建一个指针还是多个指针的区别

	char* zErrMsg = 0;  //用于保存错误信息,并初始化地址
	sqlite3* db = NULL;  //建立一个sqlite数据库指针,并初始化
	char sql1[100];  //保存SQL语句的char指针类型

	int r_row = 0;  //记录写入第几行

	char** azResult = NULL;  //查询到的信息将会保存在这里面,并初始化
	int nrow, ncolumn;  //查询到多少行、多少列

	if (sqlite3_open(".\\File\\" + s_name, &db))
	//可以是绝对路径、相对路径、或者直接写文件名
	//将获取的数据地址指向sqlite指针,之前不直接创建sqlite**是为了后面好调用方法
	{
		MessageBox(NULL, "打开数据库出现异常,请检查!", "警告!", MB_OK | MB_ICONWARNING);
		//打开失败则报错
		sqlite3_close(db);
		//关闭数据库
	}

	sprintf_s(sql1, "SELECT * FROM %s;", (LPSTR)(LPCTSTR)s_table);
	//将sqlite语句和数据库表格名称格式化保存到sql1中
	//注意:这里使用的是表格名称
	if (sqlite3_get_table(db, sql1, &azResult, &nrow, &ncolumn, &zErrMsg))
	//看上面函数原型即可得知
	{
		MessageBox(NULL, "读取数据库出现异常,请检查!", "警告!", MB_OK | MB_ICONWARNING);
		//执行方法出错则报错,报错内容可以用zErrMsg,我这用的是固定的内容,真的报错的时候不好查
	}

	for (int i = 6; i < nrow * ncolumn + 6; i++) {
	//6是列数,根据表格有多少列来设置,非固定值
	//nrow * ncolumn,类似于长乘宽,用于得知一共有多少个数据,多少个数据就读取多少次
	//i的初始值是6,和长乘宽+6的原因是,前几个数据是表格的列名称
	//比如ID、Name之类的,因为我不用,所以屏蔽调了,需要用列名称的小伙伴可以初始化为0并删掉+6
		if (i % 6 == 0)  
		//与运算,读取该行的第一列,不知道为啥能读取到第一行的小伙伴,我也不知道说啥了
		{
			r_t_str[r_row][0] = U2G(azResult[i]);
			/*将数据放置到数组指针中,逐行逐列放置,数组指针可以当做二维数组存放数据
			**因为这列的内容是中文,我用的又是VS里的多字符字节集,编码方式不同,会乱码
			**所以用了一个U2G函数转换编码方式,将UTF-8转为GB2312
			**如果使用的是Unicode字符集,应该没这种问题
			**因为U2G函数是网上找的,非个人原创,而且还看不懂(最重要的是这个)
			**我就不放了,免得被怼,有需要的可以私信我*/
		}
		else if (i % 6 == 1)
		{
			r_t_str[r_row][1] = azResult[i];
		}
		else if (i % 6 == 2) 
		{
			r_t_str[r_row][2] = azResult[i];
		}
		else if (i % 6 == 3) {
			r_t_str[r_row][3] = azResult[i];
		}
		else if (i % 6 == 4) {
			r_t_str[r_row][4] = azResult[i];
		}
		else if (i % 6 == 5) {
			r_t_str[r_row][5] = azResult[i];
		}
		r_row++;  //将数据存放到数组指针的下一行
	}

	sqlite3_free_table(azResult);
	sqlite3_close(db);
	//原型有写,不再重复

	return r_t_str;
	//将读取到的数据给有需要的人
	//为啥不返回一个CString[][],这个你可以试试,成功了告诉我

	delete[] r_t_str;
	//new创建的指针,要用delete释放,我new数组指针,所以也要在delete后加[],代表释放的是数组指针
}
上一篇:MFC之创建第一个MFC程序案例02


下一篇:Vue -自定义指令&钩子函数