VS2012+SQL2008+ODBC编程,第一篇博客,写的很差忘各位大神指点一二~

  近期写一个数据库的课程设计,用的是C++ MFC 。最開始用的是ADO技术,但是苦于网上大部分的教程都是VC6.0的,对着教程敲了4,5遍仍是执行不成功。我用的IDE是VS2012,毕竟VC6.0和VS2012之间的差距太大了,因此就改为了ODBC编程,实际上ODBC对于数据库类的操做封装的很是好,可以很是方便的使用相关的函数而且不需要本身去写一些异常处理机制,对于新手来讲是很是方便的,网上也有很是多的ODBC教程,我照着网上的VS2010的ODBC教程而后加上本身的理解写了一个学生成绩管理系统,很是easy,但是也基本上能把ODBC的思想和简单的使用方法说清楚了,声明:此文章仅适合刚刚接触数据库的新手以及相关专业的大学生,大神就可以直接忽略了,若有大神看了文章后对代码或者思想提出宝贵的改进意见,在下不胜感激!sql

 OK,废话很少说。首先打开VS2012->创建一个MFC应用程序(基于DIALOG),而后就是本身拉EDIT和BUTTON了,这个很是easy,基本学过一点MFC的都晓得怎么去弄,大小间距什么的就不具体介绍了,VS2012->格式,里面有对齐和使大小一样,本身去弄就可以了,基本上4个static,4个EDIT,四个BUTTON,一个List Control,注意的是List Control的格式设置为report数据库

这个就是个人基本界面,cno是课程号,cname是课程名,xf是学分,因为数据库中就是这么写的,因此static里面的就不变了,这个可以本身随便写,没有影响的。编程

  如下就是基本的了,首先要作的就是加入成员变量,在主对话框右键单击->类向导->成员变量,而后就是本身加入成员,这里要注意的是类型,这个类型为何要这么写,下文我会一一说明函数

  这些基础工做都作好以后,接下来就是加入ODBC使用者了,这里的ODBC使用者的加入也很是easy,类向导->加入类->MFC ODBC使用者
而后PV数据源,点击机器数据源
要注意的是这里的数据源是需要本身去配置的,具体的配置方法这里就不具体介绍了,百度上随便搜一下都有好多,也很是easy,基本上3分钟就能配置好,我这里用的数据源已是配置好的了,叫 Test,配置好数据源以后就会生成一个类,这个类的名字就是SQL 2008里面列的名字,比方我这里就是CKC,因为个人数据库中的列就是KC。如下咱们来看下这个类里面有什么内容。如下是.h文件的一些内容。
        CString m_cno;
CString m_cname;
long m_xf;


// 重写
// 向导生成的虚函数重写
public:
virtual CString GetDefaultConnect(); // 默认链接字符串


virtual CString GetDefaultSQL(); // 记录集的默认 SQL
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX 支持


// 实现
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
这是基本的代码,当中最重要的的m_cno,m_cname,m_xf当中m_cno,m_cname是CStringA类型的,仅仅只是我把它改为了CString,CStringA是和UNICODE有关的,这里咱们临时不需要考虑编码的问题,因此直接改为CString。
  这就是为何刚刚加入的成员变量的类型是CString,CString,long,要和这个类里面的类型同样。
再来看看.cpp文件的一些内容,比較重要的是
m_cno = "";
m_cname = "";
m_xf = 0;
m_nFields = 3;
m_nDefaultType = dynaset;
这个是类生成初始化的结果,GetDefaultConnect()这个函数返回的是链接字符串,里面包含DSN,UID,PSW等等,本身可以去看看,因为包含了账号和password,这里我就不贴出来了,其它的都没什么。OK,现在咱们正式開始实现对数据库的操做,在MFC界面上双击查询BUTTON,这时候咱们就会进代码界面了。
  開始,咱们要作的是对List Control进行初始化,废话很少说,上代码。
  首先,需要本身写一个初始化函数,这个函数是BOOL CXSKC::OnInitDialog(),实际上这个函数应该是在生成dlg时候就有的,但是不晓得为何我生成的时候没有,很是愚蒙,多是以前的步骤弄错了,但是这不影响,假设有的就直接在函数里面写,假设没有就本身加一个函数进去,很是easy吧。
函数里面的内容是
UpdateData(FALSE);
MyCjList.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_TWOCLICKACTIVATE);
MyCjList.InsertColumn(0,L"xf",LVCFMT_CENTER,80,0);
MyCjList.InsertColumn(0,L"cname",LVCFMT_CENTER,160,0);
MyCjList.InsertColumn(0,L"cno",LVCFMT_CENTER,80,0);
return TRUE;
这个是对List Control的一些初始化,详细含义很是easy,随便查一查都知道,没什么好说的。
  而后找到DoDataExchange()函数,在函数里面加上这些代码CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, MyCjList);
DDX_Text(pDX, IDC_EDIT1, MyCno);
DDX_Text(pDX, IDC_EDIT2, MyCname);
DDX_Text(pDX, IDC_EDIT3, MyXf);
GetDlgItem(IDC_EDIT3)->SetWindowTextW(L"");
这个也没什么好说的,都很是easy。现在,List Control就初始化好了,接下来就是重中之重了,查询的实现。SQL 中的查询语句是select * from KC where cno =。。。,因为cno是主键,为了简洁,咱们就仅仅用主键查询就可以了。
void CXSKC::OnBnClickedButton1()//这个就是查询button的代码
{
// TODO: 在此加入控件通知处理程序代码
CKC MyKC;//XS类操做对象
MyKC.Open();
MyKC.MoveFirst();
CString str1,str2,str3;
GetDlgItem(IDC_EDIT1)->GetWindowTextW(str1);
GetDlgItem(IDC_EDIT2)->GetWindowTextW(str2);
GetDlgItem(IDC_EDIT3)->GetWindowTextW(str3);

CString sql;
sql.Format(L"select * from KC where cno = '%s'",str1);
MessageBox(sql);

ListAll(sql);
}
我解释一下,要操做数据库,首先要作的就是打开数据库, CKC定义一个对象,调用open()函数,打开数据库以后把EDIT里面的内容给str, 三个EDIT相应三个str,注意顺序不要错了,否则就悲剧了。而后,需要调用一个movefirst()函数,移动到第一个记录,这样就可以从头至尾顺序的扫描表了(大概的过程就这样),毕竟不是专业的数据库project师,对于数据库的深刻理解还不够。。。而后就是sql语句了,CString 建立一个对象,用来存放sql语句 ,Format()函数真是一个好东西,我太喜欢这个函数了,它可以把后面str的内容插入‘%’,简直就是神器啊!s说明的是一个字符串,还有u,等等,有兴趣的可以本身去了解一下。MessageBox()是我用来測试SQL语句对不正确的,ListAll()函数是需要本身写的,如下是ListAll()函数的代码。
void CXSKC::ListAll(CString str)
{
MyCjList.DeleteAllItems();
MyCjList.InsertItem(0,L"");
CKC m_kc;//类的对象,用来调用操做数据库函数
try
{
if(m_kc.IsOpen())
{
m_kc.Close();
}
if(!m_kc.Open(CRecordset::snapshot,str))
{
MessageBox(L"数据库打开失败",L"数据错误",MB_OK);
return;
}
}
catch(CDBException *e)
{
e->ReportError();
}
int index = 0;
//int line = 0;
CString t;
m_kc.MoveFirst();
while(!m_kc.IsEOF())
{



//MessageBox(L"123");
MyCjList.SetItemText(index,0,m_kc.m_cno);
m_kc.m_cname.Remove(' ');
MyCjList.SetItemText(index,1,m_kc.m_cname);
//MessageBox(m_xs.m_name);
t.Format(L"%Id",m_kc.m_xf);
const TCHAR * ip = (LPCTSTR)t;
MyCjList.SetItemText(index,2,t);


m_kc.MoveNext();
index++;
}
m_kc.Close();
}
说明一下,t.Format(L"%Id",m_kc.m_xf);
    const TCHAR * ip = (LPCTSTR)t;
    MyCjList.SetItemText(index,2,t);
这两句是一个简单的类型转换,设计到LPCTSTR类型,因此有些麻烦。
这样就写好了查询BUTTONbutton了,接下来就是加入,删除和改动了,详细的思想都差点儿相同,假设查询能搞清楚,那么其它的应该很是easy就写出来,如下我把代码贴上来。
oid CXSKC::OnBnClickedButton2()//加入
{
// TODO: 在此加入控件通知处理程序代码
CString str1,str2,str3;
GetDlgItem(IDC_EDIT1)->GetWindowTextW(str1);
GetDlgItem(IDC_EDIT2)->GetWindowTextW(str2);
GetDlgItem(IDC_EDIT3)->GetWindowTextW(str3);
CString sql;//sql语句
CDatabase m_xs;//对象
m_xs.Open(L"Test",FALSE,FALSE,L"ODBC;UID=;PWD=;");
try{
if(str1.IsEmpty()||str2.IsEmpty()||str3.IsEmpty())
{
MessageBox(L"输入的信息不无缺请无缺后在插入数据",L"提示");
MyCno = (L"");
MyCname = L"";
MyXf = _ttoi(L"");
UpdateData(FALSE);
}
else
{
sql.Format(_T("insert into KC values('%s','%s','%s')"),str1,str2,str3);
MessageBox(sql);

m_xs.ExecuteSQL(sql);
MessageBox(L"加入成功!",L"提示");
//UpdateData(FALSE);
}
}
catch(CDBException ex)
{
MessageBox(L"插入异常");
ex.ReportError();
ex.Delete();
}
m_xs.Close();
}




void CXSKC::OnBnClickedButton3()//删除
{
// TODO: 在此加入控件通知处理程序代码
CString str1,str2,str3;
GetDlgItem(IDC_EDIT1)->GetWindowTextW(str1);
GetDlgItem(IDC_EDIT2)->GetWindowTextW(str2);
GetDlgItem(IDC_EDIT3)->GetWindowTextW(str3);
CString sql;//sql语句
CDatabase m_xs;//对象
m_xs.Open(L"Test",FALSE,FALSE,L"ODBC;UID=;PWD=");// 账号与password我就不写了,本身把本身的SQL的账号与password写上就好。
sql.Format(L"delete from KC where cno = '%s'",str1);
try{
if(str1.IsEmpty())
{
MessageBox(L"信息不完整",L"提示");
UpdateData(FALSE);
return;
}
else
{
//sql.Format(L"delete from KC where cno = '%S'",str1);
MessageBox(sql);

m_xs.ExecuteSQL(sql);
MessageBox(L"删除成功!",L"提示");


}
}
catch(CDBException ex)
{
ex.ReportError();
ex.Delete();
}
m_xs.Close();


}




void CXSKC::OnBnClickedButton4()//改动
{
// TODO: 在此加入控件通知处理程序代码
CString str1,str2,str3;
GetDlgItem(IDC_EDIT1)->GetWindowTextW(str1);
GetDlgItem(IDC_EDIT2)->GetWindowTextW(str2);
GetDlgItem(IDC_EDIT3)->GetWindowTextW(str3);
CString sql;//sql语句
CDatabase m_xs;//对象
m_xs.Open(L"Test",FALSE,FALSE,L"ODBC;UID=;PWD=;");
sql.Format(L"update KC set cno = '%s' , cname = '%s',xf = '%s' where cno = '%s'",str1,str2,str3,str1);
try
{
if(str1.IsEmpty()||str2.IsEmpty()||str3.IsEmpty())
{
MessageBox(L"信息输入不完整",L"提示");
UpdateData(FALSE);
return;
}
else
{
sql.Format(L"update KC set cno = '%s' , cname = '%s',xf = '%s' where cno = '%s'",str1,str2,str3,str1);
MessageBox(sql);

if(MessageBox(L"cno:"+str1+'\n'+L"cname:"+str2+'\n'+L"xf:"+str3+'\n',L"确认改动?",MB_OKCANCEL)==IDCANCEL)
{
return;
}
else
{
m_xs.ExecuteSQL(sql);
MessageBox(L"改动成功",L"提示");
}
}
}
catch(CDBException ex)
{
ex.ReportError();
ex.Delete();
}
m_xs.Close();
}
这些代码都很是easy,用CDataBase类生成一个对象,这个对象来调用ExecuteSQL(),这个函数可以运行SQL语句。
而后就是异常处理机制,这些就不详细多说了。
注意的是:1. 每调用一次open()都要调用一次close();不要忘记了,否则会出现没法操做数据库的状况,切记切记!
                    2.记得#include “afxdb.h"。仅仅有include了这个头文件以后才干用CDataBase。

剩下的就没什么好说的,主要的就是这样,假设你们还有什么意见和建议或者发现了文章有什么写的不对的地方欢迎指正~!
卖个萌 可怜哈哈~!感谢阅读!
相关文章
相关标签/搜索