MFC+SQL Serve实例

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


创建数据库

创建如下数据库

dbo.S

mfc连接sql server数据库增删改查 mfc sql server_sql


mfc连接sql server数据库增删改查 mfc sql server_mfc_02


dbo.C

mfc连接sql server数据库增删改查 mfc sql server_存储过程_03


mfc连接sql server数据库增删改查 mfc sql server_sql_04


dbo.SC

mfc连接sql server数据库增删改查 mfc sql server_数据库_05

mfc连接sql server数据库增删改查 mfc sql server_sql_06

注意:需要创建一个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 server数据库增删改查 mfc sql server_修改密码_07


并如图中添加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 server数据库增删改查 mfc sql server_修改密码_08


在对话框中添加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 server数据库增删改查 mfc sql server_修改密码_09


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
create procedure Stud
@sno char(5)
as
select * from S
where 学号=@sno

注意要分开创建,一个查询只能有一个存储

在 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 server数据库增删改查 mfc sql server_存储过程_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 server数据库增删改查 mfc sql server_修改密码_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 server数据库增删改查 mfc sql server_修改密码_12

选课操作

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

Sc 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 server数据库增删改查 mfc sql server_mfc_13

特别鸣谢: @czn @zyf