转:https://www.cnblogs.com/sunniflyer/p/4118956.html
数据库与数据库编程:
- 当前各种主流数据库有很多,包括Oracle, MS SQL Server, Sybase, Informix, MySQL, DB2, Interbase / Firebird, PostgreSQL, SQLite, SAP/DB, TimesTen, MS ACCESS等等。
- 数据库编程是对数据库的创建、读写等一列的操作。数据库编程分为数据库客户端编程与数据库服务器端编程。数据库客户端编程主要使用ODBC API、ADO、ADO.NET、OCI、OTL等方法;数据库服务端编程主要使用OLE DB等方法。
- 数据库编程需要掌握一些访问数据库技术方法,还需要注意怎么设计高效的数据库、数据库管理与运行的优化、数据库语句的优化。
ADO编程的一般步骤:
- 创建一个Connection对象
- 打开数据源,建立同数据源的连接
- 执行一个SQL命令
- 使用结果集
- 终止连接
ADO最重要的三个对象:
- 连接对象(Connection)
- 命令对象(Command)
- 记录集对象(RecordSet)
在使用这三个对象的时候,需要定义与之相对应的智能指针:_ConnectionPtr、_CommandPtr、_RecordsetPtr
使用智能指针要:定义指针变量、创建其实例(实例化)、调用方法和属性。该智能指针在析构对象时,自动调用Release方法,即使用后不需要手动释放内存,代码更加简洁。
但需要调用Close方法,关闭连接Connection或者记录集RecordSet。
一、ADO编程预处理操作
1.1 导入ADO动态链接库:
在工程的stdafx.h中加入如下语句:
#import "c:\\Program Files\\Common Files\\System\\ADO\\msado15.dll" rename_namespace("ADOCG") rename("EOF","adoEOF") //rename("BOF","adoBOF") no_namespace
using namespace ADOCG;
注:import代码要在一行中完成,换行需添加'\'
1.2 初始化OLE/COM库环境:
在基于MFC的应用里,在应用类的InitInstance成员函数中初始化OLE/COM库环境,直接使用AfxOleInit,在退出应用时,该函数自动负责COM资源的释放,比较方便,不用在
ExitInitInstance中添加相关操作:
http://baike.baidu.com/view/2798823.htm?fr=aladdin
com编程: http://baike.baidu.com/view/6923408.htm?fr=aladdin
四、实例演示
4.1 初始化引入相关的库+Connection对象的创建和数据库的连接
william_w_l 2018-08-24 12:25:06
5000 https://www.cnblogs.com/sunniflyer/p/4118956.html
http://baike.baidu.com/view/2798823.htm?fr=aladdin
com编程: http://baike.baidu.com/view/6923408.htm?fr=aladdin
四、实例演示
4.1 初始化引入相关的库+Connection对象的创建和数据库的连接
-
#import "c:\\Program Files\\Common Files\\System\\ADO\\msado15.dll" rename_namespace("ADOCG") rename("EOF","adoEOF") //rename("BOF","adoBOF")
-
using namespace ADOCG;
-
//... ...
-
_ConnectionPtr m_pConnection;
-
//... ...
-
if(!AfxOleInit())
-
{
-
AfxMessageBox("初始化OLE DLL失败!");
-
Return FALSE;
-
}
-
-
m_pConnection.CreateInstance("ADODB.Connection");
-
try
-
{
-
m_pConnection->ConnectionTimeout = 3;
-
//连接ACCESS2000
-
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:/Attendence/AttendenceDB.mdb","","",adModeUnknown);
-
}
-
catch(_com_error e)
-
{
-
AfxMessageBox(e.Description() + _T("\n数据库连接失败"));
-
}
4.2 Recordset对象的声明与创建实例:
-
_RecordsetPtr m_pRecordset;
-
m_pRecordset.CreateInstance(__uuidof(Recordset)); //创建实例
4.3 读取记录内容:
-
CString sqlHasRecord;
-
sqlHasRecord.Format("SELECT * FROM WorkUser WHERE MemberID = '%s'" , m_StringNumber);
-
HRESULT hr = m_pRecordset->Open(sqlHasRecord.GetBuffer(0), _variant_t((IDispatch*)theApp.m_pConnection, true), adOpenDynamic, adLockPessimistic, adCmdText);
-
-
if (SUCCEEDED(hr))
-
{
-
while (!m_pRecordset->adoEOF || !m_pRecordset->BOF)//遍历返回的每一条记录
-
{
-
CString m_StringID;
-
m_StringID = (LPCSTR)_bstr_t(m_pRecordset->GetCollect("FeatureID"));//读取id
-
m_pRecordset->MoveNext();
-
}
-
}
-
m_pRecordset->Close();
-
//记录用完之后需要关闭
4.4 插入新记录:
-
CString strSql;
-
strSql.Format("INSERT INTO WorkUser(MemberName, MemberID, MemberPosition, FeatureID, BeDeleted, SendedToClient) VALUES('%s', '%s', '%s', %d, 0, 0)",“ZhangSan”,”14S051000”, “Student”, 16);
-
try
-
{
-
-
(theApp.m_pConnection)->Execute(_bstr_t(strSql), 0, adCmdText);
-
}
-
catch(_com_error e)
-
{
-
MessageBox(e.Description());
-
return;
-
}
4.5 更新记录:
-
strSql.Format(_T("UPDATE WorkUser SET MemberName = '%s', MemberPosition = '%s' WHERE MemberID = '%s' "),m_StringName, m_StringPosition, m_StringNumber);
-
try
-
{
-
-
(theApp.m_pConnection)->Execute(_bstr_t(strSql), 0, adCmdText);
-
}
-
catch(_com_error e)
-
{
-
MessageBox(e.Description());
-
return;
-
}
4.6 删除记录:
-
CString strSql;
-
strSql.Format(_T("DELETE FROM WorkUser WHERE FeatureID = %s "), FeatureID[i]);
-
try
-
{
-
(theApp.m_pConnection)->Execute(_bstr_t(strSql), 0, adCmdText);
-
}
-
catch(_com_error e)
-
{
-
MessageBox(e.Description());
-
return FALSE;
-
}
4.7 读取字节流文件:
读取图像数据:
-
try
-
{
-
CString sql;
-
sql.Format("select * from WorkUser where MemberID='%s'",MemberID);
-
-
HRESULT hr = m_pRecordset->Open(sql.GetBuffer(0),_variant_t((IDispatch *)theApp.m_pConnection,true),adOpenDynamic,adLockPessimistic,adCmdText);
-
if(SUCCEEDED(hr))
-
{
-
if(m_pRecordset->adoEOF||m_pRecordset->BOF)
-
{
-
-
MessageBox(_T("数据库中没有相应的记录"));
-
return;
-
}
-
else
-
{
-
long lDataSize = m_pRecordset->GetFields()->GetItem(imgColName.GetBuffer(0))->ActualSize;
-
if (lDataSize>0)
-
{
-
_variant_t varBLOB;
-
varBLOB = m_pRecordset->GetFields()->GetItem(imgColName.GetBuffer(0))->GetChunk(lDataSize);
-
if(varBLOB.vt == (VT_ARRAY | VT_UI1))
-
{
-
if(buffer) ///重新分配必要的存储空间
-
{
-
char *pBuf = NULL;
-
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
-
memcpy(buffer,pBuf,lDataSize); ///复制数据到缓冲区buffer
-
SafeArrayUnaccessData (varBLOB.parray);
-
-
}
-
}
-
}
-
else
-
{
-
MessageBox(_T("数据库中的图像数据为空!"));
-
return;
-
}
-
}
-
}
-
}
-
catch (...)
-
{
-
MessageBox(_T("数据库访问出错"));
-
}
-
m_pRecordset->Close();
4.8 保存字节流文件:
-
CString sql;
-
sql.Format("select * from WorkUser where MemberID='%s'",MemberID);
-
HRESULT hr = m_pRecordset->Open(sql.GetBuffer(0),_variant_t((IDispatch *)theApp.m_pConnection,true),adOpenDynamic,adLockPessimistic,adCmdText);
-
-
if(SUCCEEDED(hr))
-
{
-
if (!m_pRecordset->adoEOF||!m_pRecordset->BOF)
-
{
-
-
-
char *pBuf = buffer;
-
VARIANT varBLOB;
-
SAFEARRAY *psa;
-
SAFEARRAYBOUND rgsabound[1];
-
if(pBuf)
-
{
-
rgsabound[0].lLbound = 0;
-
rgsabound[0].cElements = bufLength;
-
psa = SafeArrayCreate(VT_UI1, 1, rgsabound); //分配的数据类型为unsigned int (1 byte 长度的类型)
-
for (long i = 0; i < (long)bufLength; i++)
-
SafeArrayPutElement (psa, &i, pBuf++);
-
-
varBLOB.vt = VT_ARRAY | VT_UI1;
-
varBLOB.parray = psa;
-
m_pRecordset->GetFields()->GetItem(imgColName.GetBuffer(0))->AppendChunk(varBLOB);
-
}
-
m_pRecordset->Update();
-
}
-
else
-
{
-
MessageBox(_T("数据库中没有相应用户的记录!"));
-
return;
-
}
-
-
}
-
m_pRecordset->Close();
-