1.MFC ODBC数据库开发技术
1.利用ODBC建立数据源
2.数据库连接
1).包含头文件 #include <afxdb.h>
2).对数据源进行操作之前需要定义一个CDatabase对象,代码如下
CDatabase m_db;
3).调用CDatabase的成员函数OpenEx建立和数据源的连接,代码如下
try
{
m_db.OpenEx(L"DSN=test;UID=sa;PWD=", CDatabase::noOdbcDialog);
}
catch(_com_error e)
{
MessageBox(L"连接数据库失败");
}
其中DSN为数据源名称,UID数据库用户名,PWD为相应的密码
3.数据库操作
查询记录
CRecordset rs(&m_db); //CRecordset rs; rs = &m_db;
rs.Open(CRecordset::dynaset, L"SELECT * FROM test"); //详见MSDN
获得字段值
GetFieldValue
添加,删除,修改记录方法如下
1.先定义相应操作的SQL语句
2.调用ExecuteSQL函数即可
ADO数据库开发技术
1.ADO是Windows环境中比较流行的数据库编程技术。它是建立在OLE DB底层技术之上的高级编程接口,因而具有强大的数据处理功能和简单易用的编程接口,并且得到了广泛的应用。
ADO的底层是OLE DB(微软的战略性的通向不同的数据源的低级应用程序接口),所以不仅能访问关系型数据库,也可以访问非关系型数据库,更是现在最快速的数据库访问中间层。
2.ADO主要对象介绍
1).
Connection Object(连接对象)
Command Object(命令对象)
RecordSet Object(记录集对象)
Field Object(字段对象)
Record Object(记录对象)
Error Object(错误对象)
Parameter Object(参数对象)
Property Object(属性对象)
Stream Object(流对象)
其中最重要的是Connection Object(连接对象),Command Object(命令对象),RecordSet Object(记录集对象)
Connection Object:连接对象代表了一个和数据源的连接,之后的数据库操作都是建立在这个连接上。
Command Object:命令对象用来处理数据库的一些操作,在某些方面具有和连接对象相同的功能,例如都可以可行标准的SQL语句以及存储过程,不过命令对象可以返回带有记录集的结果。
RecordSet Object:记录集对象代表了一个记录集,用来访问记录集。
在使用这三个对象之前,需要定义与之对应的3个职能指针,分别为_ConnectionPtr, _CommandPtr, _RecordsetPtr,然后调用它们的CreateInstance函数进行实例化,从而创建这3个对象的实例。
2)._bstr和_variant_t类
在利用ADO进行数据库开发时,_bstr_t和_variant_t两个类很有用,从来省去了BSTR和VARIANT类型转换的麻烦。
COM编程不适用CString类,因为COM必须设计成跨平台,它需要一种更普遍的方式来处理字符串以及其他数据类型。
3).引入ADO库
在StdAfx.h末尾处引入ADO库文件
#import "C:/Program Files/Common Files/System/ado" no_namespace rename("EOF", "adoEOF")
使用预处理指令import使程序在编译过程中引入ADO动态库(msado115.dll).no_namespace表明不使用命名空间。rename("EOF", "adoEOF")表明把ADO中用到EOF改为adoEOF,防止发生命名冲突。
注意:利用应用程序向导进行ADO数据库开发时,需要在程序向导的第二步选择(Automation)选项,使应用程序能够支持“自动操作”的方式。
数据库连接
_ConnectionPtr m_pConnection; //定义一个_ConnectionPtr指针
m_pConnection.CreateInstance(_uuidof(Connection)); //调用CreateInstance方法实例化
最后,调用Connection对象的Open函数创建数据库连接,Open函数原型如下。
HRESULT Open(
_bstr_t ConnectiongString,
_bstr_t UserID,
_bstr_t Password,
long Options);
其中,ConnectionString是一个包含连接信息的字符串,UerID是访问数据库的用户名,Password是访问数据库的秘密,Options为可选参数。如果在ConnectiongString中包含了数据库用户名和密码,UerID和Password值可以为空。
下面附上一些代码说明(代码为我写的“壁虎桌面日历”部分代码)
连接数据库
m_pConn.CreateInstance(__uuidof(Connection));
wchar_t wPath[200];
GetModuleFileName(NULL,wPath,200);
PathRemoveFileSpec(wPath);
wcscat(wPath,L"//AnyCaler.mdb");
wchar_t wConn[400];
wsprintf(wConn,L"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = %s; Persist Security Info=FALSE",wPath);
try
{
m_pConn->Open(wConn, "", "", adConnectUnspecified);
}
catch(_com_error e)
{
/*
CString errorMsg;
errorMsg.Format(_T("连接数据库失败!/n%s"), e.ErrorMessage());
LPCTSTR errMsg;
errMsg = (const WCHAR*)(errorMsg.AllocSysString());
AfxMessageBox(errMsg);*/
MessageBox(NULL,L"数据库连接失败!",L"警告",MB_ICONWARNING);
exit(0);
}
查询 添加记录 修改记录
_RecordsetPtr rst;
_variant_t var;
HRESULT hr;
rst.CreateInstance(_uuidof(Recordset)); //打开连接
char sqlStr[100] = {0};
sprintf(sqlStr, "SELECT * FROM MemoInfo WHERE Date = '%d-%d-%d'",
m_MemoDlg.m_year, m_MemoDlg.m_month, m_MemoDlg.m_date);
try
{
hr = rst->Open(sqlStr, m_pConn.GetInterfacePtr(), adOpenDynamic,adLockOptimistic,adCmdText);
}
catch(_com_error *e)
{
AfxMessageBox(e->ErrorMessage());
}
if (rst->adoEOF)
{
rst->AddNew();
rst->PutCollect("Date", _variant_t(tempDateStr));
rst->PutCollect("Time", _variant_t(tempTimeStr));
rst->PutCollect("Memo", _variant_t(m_memo));
rst->PutCollect("Warn", _variant_t(m_MemoDlg.checkRemind));
rst->PutCollect("Shark", _variant_t(m_MemoDlg.checkShake));
rst->PutCollect("Card", _variant_t(m_MemoDlg.checkPopWindow));
rst->PutCollect("Sound", _variant_t(m_MemoDlg.checkPopWindow));
rst->PutCollect("Del", _variant_t("1"));
rst->Update();
}
else
{
rst->PutCollect("Date", _variant_t(tempDateStr));
rst->PutCollect("Time", _variant_t(tempTimeStr));
rst->PutCollect("Memo", _variant_t(m_memo));
rst->PutCollect("Warn", _variant_t(m_MemoDlg.checkRemind));
rst->PutCollect("Shark", _variant_t(m_MemoDlg.checkShake));
rst->PutCollect("Card", _variant_t(m_MemoDlg.checkPopWindow));
rst->PutCollect("Sound", _variant_t(m_MemoDlg.checkPopWindow));
rst->PutCollect("Del", _variant_t("1"));
rst->Update();
}
rst->Close();
rst = NULL;
删除
rst->Delete(adAffectCurrent);
备注:_ConnectionPtr对象可申明为全局变量,在App的InitInstance函数中连接数据源,在ExitInstance断开数据源连接;每个_RecordSet指针在使用完之后记得Close并附空值。
还可以利用ADO数据控件进行数据库编程,具体参考Visual C++ SQL Server数据库开发与实例