【MFC】vs2019中使用sqlite3完成学生管理系统

效果图

在这里插入图片描述
使用sqlite3完成简单的数据库操作。

list Contral 控件的简单使用

本章只介绍基本应用

	添加表头:

语法

int InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat = LVCFMT_LEFT, int nWidth = -1, int nSubItem = -1);

nCol:表示列
lpszColumnHeading:表示常量字符串指针
nFormat:表示样式,LVCFMT_LEFT(左对齐)
nWidth:列宽度
nSubItem:指定列对应的子项索引,默认值-1

使用:
//设置样式
m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
m_listCtrl.InsertColumn(0, _T("学号"), LVCFMT_LEFT, 80);
m_listCtrl.InsertColumn(1, _T("姓名"), LVCFMT_LEFT, 80);
m_listCtrl.InsertColumn(2, _T("年龄"), LVCFMT_LEFT, 80);
m_listCtrl.InsertColumn(3, _T("成绩"), LVCFMT_LEFT, 80);
	添加子项

语法

int InsertItem(int nItem, LPCTSTR lpszItem);
bool SetItemText(int nItem, int nSubItem, LPCTSTR lpszText);

nItem:索引 行,默认-1会插到末尾
nSubItem:索引 列
lpszItem:常量字符串指针

使用:
InsertItem(i, _T(""));
SetItemText(i, j, str);
	清空列表
DeleteAllItems();
这个函数没有参数,它会直接删除CListCtrl控件中的所有项目。
当调用这个函数后,列表视图将变为空的状态,之前所有插入的行都将被清除。

使用sqlite3

环境:vs2019
使用sqlite3主要是通过以下函数

语法:sqlite3_open

int sqlite3_open(const char *filename, sqlite3 **ppDb);

作用:打开或者创建一个数据库
filename: 路径 。如果不存在则创建数据库
ppDb: 指向sqlite3 类型指针的指针。创建成功后会指向一个sqlite3 对象,通过这个对象对数据库进行操作

使用:
	sqlite3* db=NULL;
	int rc = sqlite3_open("./db/text.db", &db);
	if (rc != SQLITE_OK)
	{
		AfxMessageBox(_T("链接数据库失败"));
		return;
	}

int sqlite3_close(sqlite3*);

作用:关闭数据库
使用:
	sqlite3_close(db);

语法:sqlite3_exec


int sqlite3_exec(sqlite3 *db, const char *sql, 
	int (*callback)(void*, int, char**, char**), 
	void *arg, char **errmsg);

sql: 需要执行的sql语句

参数三: 回调函数,看这个回调函数的参数类型,不难猜出,这个函数
是用来处理查询语句(select)的结果的。如果不是查询语句,设置NULL即可

arg是sqlite3_exec函数的arg参数传递过来的值;
nCol是查询结果中的列数;
colVal是一个指向字符数组的指针,用于存储每一列的值;
colName是一个指向字符数组的指针,用于存储每一列的名称。

arg:这是一个void类型的指针,用于传递给回调函数的额外参数。

可以是任何类型的数据,通过这个参数可以在回调函数中获取外部传递进来的信息。
errmsg: 用来存储错误信息的,执行成功会被设置NULL,失败会有错误信息

使用:
	const std::string str = "CREATE TABLE IF NOT EXISTS Students("
				"id TEXT PRIMARY KEY,"
				"name TEXT,"
				"age INTEGER,"
				"grades REAL);";

	sqlite3_exec(db, str.c_str(), NULL, NULL, NULL);
	if (rc != SQLITE_OK) {
		AfxMessageBox(_T("创建表失败"));
		return;
	}

语法:sqlite3_get_table

int sqlite3_get_table(sqlite3* db, const char* zSql, 
	char*** pazResult, int* pnRow, int* pnColumn, 
	char** pzErrmsg);
	
作用: 和sqlite3_exec的回调函数相似

pazResult: 存放的是查询后的结果集
pnRow: 行
pnColumn: 列

使用:
	char** mResult;//结果集
	int mRow;//行数
	int mCol;//列数
	int nResult = sqlite3_get_table(Cdb.db, sql, &mResult, &mRow, &mCol, NULL);
	int nIndex = mCol;
	if (nResult == SQLITE_OK)
	{
		for (int i = 0; i < mRow; i++)
		{
			m_listCtrl.InsertItem(i, _T(""));
			for (int j = 0; j < mCol; j++)
			{
				CString str;
				str = mResult[nIndex];

				if (!strcmp("id", mResult[j]))
				{
					m_listCtrl.SetItemText(i, j, str);
				}
				else if (!strcmp("name", mResult[j]))
				{
					m_listCtrl.SetItemText(i, j, str);
				}
				else if (!strcmp("age", mResult[j]))
				{
					m_listCtrl.SetItemText(i, j, str);
				}
				else if (!strcmp("grades", mResult[j]))
				{
					m_listCtrl.SetItemText(i, j, str);
				}
				nIndex++;
			}
		}

要深刻理解mResult 才可以理解代码

配套使用的还有
void sqlite3_free_table(char **result);
用来释放存储结果集的空间,防止内存泄漏

使用:
	sqlite3_free_table(mResult);

语法:sqlite3_prepare_v2

int sqlite3_prepare_v2(sqlite3 *db, const char *zSql, int nByte, 
sqlite3_stmt **ppStmt, const char **pzTail);

nByte:表示sql字符的长度,通常设置-1,编辑器自动计算长度
ppStmt:这是一个指向sqlite3_stmt类型指针的指针。
用于存储预处理后的 SQL 语句对象。
在成功预处理 SQL 语句后,*ppStmt会指向一个有效的sqlite3_stmt对象,
这个对象在后续的sqlite3_step函数执行过程中会被使用。
pzTail:通常设置NULL


int sqlite3_step(sqlite3_stmt *pStmt);
返回值:SQLITE_DONE:表示非查询语句已经成功执行完毕。
例如,插入一条记录成功、更新或删除指定数据成功后,都会返回SQLITE_DONE。
SQLITE_ERROR:错误
SQLITE_NOMEM:内存不足
SQLITE_ROW:用于查询,当返回这个说明还没有执行完

配套使用的还有
int sqlite3_finalize(sqlite3_stmt *pStmt);
释放存放sql语句的内存

使用:
	sqlite3_stmt* stmt = NULL;        //stmt语句句柄
	int result = sqlite3_prepare_v2(Cdb.db, sql, -1, &stmt, NULL);
	if (result == SQLITE_OK)
	{
		int stepResult = sqlite3_step(stmt);
		if (stepResult == SQLITE_DONE)
		{
			AfxMessageBox(_T("删除成功"));
			OnBnClickedButton1();
		}
		else
		{
			AfxMessageBox(_T("执行 SQL 语句失败"));
		}
	}
	else
	{
		AfxMessageBox(_T("准备 SQL 语句失败"));
	}

	if (stmt != NULL)
	{
		sqlite3_finalize(stmt);
	}

SQLite 库中一个用于将 SQL 语句编译为字节码程序的函数,它是执行 SQL 语句(特别是那些带有参数或者需要更精细控制执行过程的语句)的重要前置步骤。通过这个函数,可以对 SQL 语句进行预处理,之后可以使用sqlite3_step函数来逐步执行预处理后的语句。这种方式比直接使用sqlite3_exec函数更灵活,适用于复杂的数据库操作,如带有参数绑定的插入、更新、删除操作以及需要逐行处理的查询操作等。

sqlite3_step,用于执行在sqlite3_prepare_v2中已经准备好的 SQL 语句的下一个步骤。对于查询语句,它会逐行获取结果;对于非查询语句(如插入、更新、删除),它会执行语句直到完成相应的操作。

语法:sqlite3_bind_text
再使用sqlite3_prepare_v2执行相对复杂的语句时,需要用到占位符
sqlite3_bind_text函数是用来替换占位符的

下面是修改操作

	sqlite3_stmt* stmt = NULL;        //stmt语句句柄
	const char* str = "update Students set name = ?, age = ?,grades = ? where id=?;";
	int result = sqlite3_prepare_v2(Cdb.db, str, -1, &stmt, NULL);
	if (result == SQLITE_OK)
	{
		std::string id = (CT2A(m_strId));
		std::string name = (CT2A(m_strName));
		sqlite3_bind_text(stmt, 1, name.c_str(), -1, SQLITE_TRANSIENT);
		sqlite3_bind_int(stmt, 2, m_strAge);
		sqlite3_bind_double(stmt, 3, m_iGrades);
		sqlite3_bind_text(stmt, 4, id.c_str(), -1, SQLITE_TRANSIENT);
		int stepResult = sqlite3_step(stmt);
		if (stepResult == SQLITE_DONE)
		{
			AfxMessageBox(_T("修改成功"));
		}
		else
		{
			AfxMessageBox(_T("执行 SQL 语句失败"));
		}
	}
	else
	{
		AfxMessageBox(_T("准备 SQL 语句失败"));
	}

	if (stmt != NULL)
	{
		sqlite3_finalize(stmt);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世_生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值