MFC+SQL Serve实例

MFC+SQL Serve实例

    • 创建数据库
    • MFC连接数据库
    • 获取选课信息
    • 修改密码
    • 选课操作

创建数据库

创建如下数据库
dbo.S
MFC+SQL Serve实例_第1张图片
MFC+SQL Serve实例_第2张图片
dbo.C
MFC+SQL Serve实例_第3张图片
MFC+SQL Serve实例_第4张图片
dbo.SC

MFC+SQL Serve实例_第5张图片

MFC+SQL Serve实例_第6张图片

注意:需要创建一个txt,并把后缀改为udl,右键属性,连接你创建的数据库,测试连接后,改回txt,获取其中字符串。

MFC连接数据库

创建MFC项目->基于对话框
这里创建的项目名称为Test
在 stdafx.h 添加以下代码:

#import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace rename("EOF" , "adoEOF") rename("BOF", "adoBOF")

注意要在一行内,分多行需在行末加 " \ "

在 Test.h 中的 public 添加以下代码:

_ConnectionPtr m_pCon;
BOOL ConnectDataBase(CString strLinkWord);

在 Test.cpp 中的 InitInstance() 函数添加以下代码:

	CString strLinkWord = L"Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=StudentManagement;Data Source=DESKTOP-EDQ3AKC";
	if (!ConnectDataBase(strLinkWord))
	{
     
		return FALSE;
	}
	AfxMessageBox(L"Succeedly!");

strLinkWord中的字符串即为你从udl中获取的字符串
MFC+SQL Serve实例_第7张图片
并如图中添加dlg.m_pCon = m_pCon; 来传递指针
注意需在TestDlg.h 中先定义指针,不然会提示不存在m_pCon

我们之前声明了ConnectDataBase()函数,现在来定义它,在Test.cpp任意位置添加以下代码:

BOOL CTestApp::ConnectDataBase(CString strLinkWord)
{
     
	// TODO: 在此处添加实现代码.
	::CoInitialize(NULL);

	if (!SUCCEEDED(m_pCon.CreateInstance(__uuidof(Connection))))
	{
     
		m_pCon = NULL;
		TRACE("Failed!");
	}
	ASSERT(m_pCon != NULL);
	try
	{
     
		return SUCCEEDED(m_pCon->Open(_bstr_t(strLinkWord), _bstr_t(L""), _bstr_t(L""), adModeUnknown));
	}
	catch (_com_error & e)
	{
     
		CString str;
		str.Format(L"%s\n", e.ErrorMessage());
		AfxMessageBox(str);
		return FALSE;
	}
}

注意CTestApp改为你自己创建项目的名字

在 TestDlg.h 中的 public 添加以下代码:

	_ConnectionPtr m_pCon;
	_RecordsetPtr m_pRec;
	_RecordsetPtr DBRecordSetGet(LPCTSTR Sql);
	BOOL GetCollect(LPCTSTR Name,_variant_t& OutCol);
	
	CString m_sno;//学号
	CString m_pw;//密码

如果指针m_pCon在之前那步定义了,这里就不用重复定义

先在 TestDlg.cpp 中定义声明的两个函数:

_RecordsetPtr CTestDlg::DBRecordSetGet(LPCTSTR Sql)
{
     
	// TODO: 在此处添加实现代码.
	m_pRec.CreateInstance("ADODB.Recordset");
	m_pRec = m_pCon->Execute((_bstr_t)Sql, NULL, adCmdText);
	return m_pRec;
	//return _RecordsetPtr();
}


BOOL CTestDlg::GetCollect(LPCTSTR Name, _variant_t& OutCol)
{
     
	// TODO: 在此处添加实现代码
	_variant_t vt;
	vt = m_pRec->GetCollect(Name);
	if (vt.vt != VT_NULL) {
     
		OutCol = vt;
		return TRUE;
	}
	else
		return FALSE;
}

MFC+SQL Serve实例_第8张图片
在对话框中添加2个 Edit Control
双击确定按钮,创建Button函数,添加以下代码:

	GetDlgItemText(IDC_EDIT1, m_sno);
	GetDlgItemText(IDC_EDIT2, m_pw);

	CString sql;
	sql.Format(L"exec Login '%s','%s'", m_sno, m_pw);//存储过程
	m_pRec = DBRecordSetGet(sql);

	_variant_t var;
	GetCollect(L"cnt", var);//cnt 与你创建的存储过程里的名称对应
	int temp = var.intVal;

	if (temp == 1)
	{
     
		Info dlg;
		dlg.m_pCon = m_pCon;
		dlg.m_sno = m_sno;
		dlg.DoModal();
	}
	else
		MessageBox(L"Error!");

这里用到了 学生信息对话框,所以需先在 资源视图 插入 新对话框,并右键对话框,添加类:Info.h
Info.h 中一样要先定义指针和学号,不过你可以先忽略红色警告,在后面步骤中再添加
在 TestDlg.cpp 中引入#include"Info.h"
将学生信息对话框做如下布局:
MFC+SQL Serve实例_第9张图片
Edit Control 修改一下属性,可以改成无边框背景,列表为 List Control

上面代码中用到了存储过程,我们得先去SSMS创建存储过程:

create procedure Login
@sno char(5),@pw varchar(20)
as
select COUNT(*) as cnt from S
where 学号=@sno and 密码=@pw

在 Info.h 的 public 中添加:

	CString m_sno;

	_ConnectionPtr m_pCon;
	_RecordsetPtr m_pRec;
	_RecordsetPtr DBRecordSetGet(LPCTSTR Sql);
	BOOL GetCollect(LPCTSTR Name, _variant_t& OutCol);

注意所有对话框都用到了上面声明的2个函数,都需要在相应cpp中定义:

_RecordsetPtr CTestDlg::DBRecordSetGet(LPCTSTR Sql)
{
     
	// TODO: 在此处添加实现代码.
	m_pRec.CreateInstance("ADODB.Recordset");
	m_pRec = m_pCon->Execute((_bstr_t)Sql, NULL, adCmdText);
	return m_pRec;
	//return _RecordsetPtr();
}


BOOL CTestDlg::GetCollect(LPCTSTR Name, _variant_t& OutCol)
{
     
	// TODO: 在此处添加实现代码
	_variant_t vt;
	vt = m_pRec->GetCollect(Name);
	if (vt.vt != VT_NULL) {
     
		OutCol = vt;
		return TRUE;
	}
	else
		return FALSE;
}

之后就不再赘述。

在信息对话框右键->类向导->虚函数 添加OnInitDialog()
并在其中添加:

	CString sql;
	sql.Format(L"exec Stud '%s'", m_sno);
	m_pRec = DBRecordSetGet(sql);

	_variant_t var;
	CString str;
	str.Format(L"学号:%s", m_sno);
	SetDlgItemText(IDC_EDIT1, str);

	GetCollect(L"姓名", var);
	CString temp = var.bstrVal;
	str.Format(L"姓名:%s", temp);
	SetDlgItemText(IDC_EDIT2, str);

	GetCollect(L"所在系", var);
	CString a = var.bstrVal;
	str.Format(L"所在系:%s", a);
	SetDlgItemText(IDC_EDIT3, str);

	GetCollect(L"性别", var);
	CString b = var.bstrVal;
	str.Format(L"性别:%s", b);
	SetDlgItemText(IDC_EDIT4, str);

	GetCollect(L"年龄", var);
	int c = var.intVal;
	str.Format(L"年龄:%d", c);
	SetDlgItemText(IDC_EDIT5, str);

我们可以先运行一下:
MFC+SQL Serve实例_第10张图片
连接成功,登录正确密码后获得学生信息

获取选课信息

给List Control添加变量,右键列表,变量名:m_list
并在Info.cpp 的 OnInitDialog() (就是刚刚创建的)
中添加:

	m_list.ModifyStyle(LVS_ICON | LVS_SMALLICON | LVS_LIST, LVS_REPORT);
	m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
	m_list.InsertColumn(0, L"课程号"); m_list.InsertColumn(1, L"课程名");
	m_list.InsertColumn(2, L"学时数"); m_list.InsertColumn(3, L"任课老师");
	m_list.InsertColumn(4, L"成绩");
	RECT rect;
	m_list.GetWindowRect(&rect); int wid = (rect.right - rect.left) / 7;//wid 格宽度
	m_list.SetColumnWidth(0, wid); m_list.SetColumnWidth(1, 2 * wid);
	m_list.SetColumnWidth(2, wid); m_list.SetColumnWidth(3, wid);
	m_list.SetColumnWidth(4, 2 * wid);

	LoadData();

这里的 LoadData() 为数据加载函数,需自己创建
在 Info.h 的 public 中声明:void LoadData();
并在 Info.cpp 中添加:

void Info::LoadData()
{
     
	// TODO: 在此处添加实现代码.
	CString sql;
	sql.Format(L"exec Scla '%s'", m_sno);
	m_pRec = DBRecordSetGet(sql);

	if (m_pRec == NULL)
		return;

	m_list.DeleteAllItems();
	int j = 0;
	while (!m_pRec->adoEOF)
	{
     
		m_list.InsertItem(j, L"");
		_variant_t var;

		m_list.SetItemText(j, 0, (LPTSTR)(_bstr_t)m_pRec->GetCollect("课程号"));
		m_list.SetItemText(j, 1, (LPTSTR)(_bstr_t)m_pRec->GetCollect("课程名"));
		m_list.SetItemText(j, 2, (LPTSTR)(_bstr_t)m_pRec->GetCollect("学时数"));
		m_list.SetItemText(j, 3, (LPTSTR)(_bstr_t)m_pRec->GetCollect("任课老师"));
		var = m_pRec->GetCollect("成绩");
		if (var.vt != VT_NULL)
		{
     
			m_list.SetItemText(j, 4, (LPTSTR)(_bstr_t)var);
		}
		else
			m_list.SetItemText(j, 4, TEXT(""));
		m_pRec->MoveNext();
		j++;
	}
}

上面用到了存储过程Scla,同样得去SSMS创建:

create procedure Scla
@sno char(5)
as
select C.课程号,C.课程名,C.任课老师,C.学时数,SC.成绩
from SC,C
where C.课程号=SC.课程号 and 学号=@sno

查看运行结果:
MFC+SQL Serve实例_第11张图片

修改密码

在信息对话框添加新Button,名字改为修改密码,双击创建Button函数。

并在 资源视图 新建 修改密码对话框,添加类:Pw.h
在 Pw.h 的 public 中添加:

	CString m_sno;
	CString m_pw;

	_ConnectionPtr m_pCon;
	_RecordsetPtr m_pRec;
	_RecordsetPtr DBRecordSetGet(LPCTSTR Sql);
	BOOL GetCollect(LPCTSTR Name, _variant_t& OutCol);

*记得在cpp中添加那2个函数定义!

我们先回到 Info.cpp 中引入#include"Pw.h"
在 OnBnClickedButton1() 函数中,添加:

	Pw dlg;
	dlg.m_pCon = m_pCon;
	dlg.m_sno = m_sno;
	dlg.DoModal();

再回到修改密码对话框,添加 Edit Control,
双击确定按钮创建 OnBnClickedOk() ,在其中添加:

	GetDlgItemText(IDC_EDIT1, m_pw);
	CString sql;
	sql.Format(L"exec Cpw '%s','%s'", m_sno, m_pw);
	m_pRec = DBRecordSetGet(sql);
	MessageBox(L"修改成功!");

上面用到存储过程:

create procedure Cpw
@sno char(5),@pw varchar(20)
as
update S
set 密码=@pw
where S.学号=@sno

现在可以运行查看修改密码结果
MFC+SQL Serve实例_第12张图片

选课操作

在Info对话框新建按钮,双击进入Info.cpp
引入:#include"Sc.h"
并在 OnBnClickedButton2() 添加:

	S dlg;
	dlg.m_pCon = m_pCon;
	dlg.m_sno = m_sno;
	if (dlg.DoModal() == IDOK)
		LoadData();

新建 选课 对话框,添加类:Sc.h
在对话框添加List Control
给List Control添加变量,右键列表,变量名:m_list

双击列表创建:OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
双击确定创建:OnBnClickedOk()

在对话框右键->类向导->虚函数 添加OnInitDialog()

在 Sc.h 的 public 中添加:

	CString m_sno;
	CString sel;

	_ConnectionPtr m_pCon;
	_RecordsetPtr m_pRec;
	_RecordsetPtr DBRecordSetGet(LPCTSTR Sql);
	BOOL GetCollect(LPCTSTR Name, _variant_t& OutCol);
	void LoadData();

*记得在cpp中添加那2个函数定义!

添加LoadData :

void Sc::LoadData()
{
     
	// TODO: 在此处添加实现代码.
	CString sql;
	sql.Format(L"exec UnScla '%s'", m_sno);
	m_pRec = DBRecordSetGet(sql);

	if (m_pRec == NULL)
		return;

	m_list.DeleteAllItems();
	int j = 0;
	while (!m_pRec->adoEOF)
	{
     
		m_list.InsertItem(j, L"");
		_variant_t var;

		m_list.SetItemText(j, 0, (LPTSTR)(_bstr_t)m_pRec->GetCollect("课程号"));
		m_list.SetItemText(j, 1, (LPTSTR)(_bstr_t)m_pRec->GetCollect("课程名"));
		m_list.SetItemText(j, 2, (LPTSTR)(_bstr_t)m_pRec->GetCollect("学时数"));
		m_list.SetItemText(j, 3, (LPTSTR)(_bstr_t)m_pRec->GetCollect("任课老师"));

		m_pRec->MoveNext();
		j++;
	}
}

在Sc.cpp 的 OnInitDialog() 中添加:

	m_list.ModifyStyle(LVS_ICON | LVS_SMALLICON | LVS_LIST, LVS_REPORT);
	m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
	m_list.InsertColumn(0, L"课程号"); m_list.InsertColumn(1, L"课程名");
	m_list.InsertColumn(2, L"学时数"); m_list.InsertColumn(3, L"任课老师");
	RECT rect;
	m_list.GetWindowRect(&rect); int wid = (rect.right - rect.left) / 7;//wid 格宽度
	m_list.SetColumnWidth(0, wid); m_list.SetColumnWidth(1, 2 * wid);
	m_list.SetColumnWidth(2, wid); m_list.SetColumnWidth(3, wid);

	LoadData();

在Sc.cpp 的 OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult) 中添加:

	int i = m_list.GetSelectionMark();
	sel = m_list.GetItemText(i, 0);

在Sc.cpp 的 OnBnClickedOk() 中添加:

	CString sql;
	sql.Format(L"exec Ins '%s','%s'", m_sno, sel);
	m_pRec = DBRecordSetGet(sql);
	if (m_pRec == NULL)
		return;
	else
		MessageBox(L"Succeed");

以上代码用到的存储过程:

create procedure UnScla
@sno char(5)
as
select 课程号,课程名,任课老师,学时数
from C
where 课程号 not in (select 课程号 from SC where 学号=@sno)
create procedure Ins
@sno char(5),@cno char(5)
as
insert into SC(学号,课程号)
values(@sno,@cno)

以上就是全部代码,赶紧运行查看结果吧!
MFC+SQL Serve实例_第13张图片

特别鸣谢: @czn @zyf

你可能感兴趣的:(C++,SQL,sql,数据库,mfc)