📄 ado.cpp
字号:
------------------------------------------------
事务处理
------------------------------------------------
BeginTrans - 开始新事务。
CommitTrans - 保存任何更改并结束当前事务。它也可能启动新事务。
RollbackTrans - 取消当前事务中所作的任何更改并结束事务。它也可能启动
新事务。
一旦调用了 BeginTrans 方法,在调用 CommitTrans 或 RollbackTrans 结
束事务之前,数据库将不再立即提交所作的任何更改。
对于支持嵌套事务的数据库来说,在已打开的事务中调用 BeginTrans 方法
将开始新的嵌套事务。返回值将指示嵌套层次:返回值为 1 表示已打开顶层事务
(即事务不被另一个事务所嵌套),返回值为 2 表示已打开第二层事务(嵌套
在顶层事务中的事务),依次类推。调用 CommitTrans 或 RollbackTrans 只影
响最新打开的事务;在处理任何更高层事务之前必须关闭或回卷当前事务。
调用 CommitTrans 方法将保存连接上打开的事务中所做的更改并结束事务。
调用 RollbackTrans方法还原打开事务中所做的更改并结束事务。在未打开事务
时调用其中任何一种方法都将引发错误。
取决于 Connection 对象的 Attributes 属性,调用 CommitTrans 或
RollbackTrans 方法都可以自动启动新事务。如果 Attributes 属性设置为
adXactCommitRetaining,数据库在 CommitTrans 调用后会自动启动新事务。
如果 Attributes 属性设置为 adXactAbortRetaining,数据库在调用
RollbackTrans 之后将自动启动新事务。
########################################################################*/
long CAdoConnection::BeginTrans()
{
ASSERT(m_pConnection != NULL);
try
{
return m_pConnection->BeginTrans();
}
catch (_com_error e)
{
TRACE(_T(":( BeginTrans发生错误: %s\n"), e.ErrorMessage());
return -1;
}
return -1;
}
BOOL CAdoConnection::CommitTrans()
{
ASSERT(m_pConnection != NULL);
try
{
return SUCCEEDED(m_pConnection->CommitTrans());
}
catch (_com_error e)
{
TRACE(_T(":( CommitTrans发生错误: %s\n"), e.ErrorMessage());
return FALSE;
}
return FALSE;
}
BOOL CAdoConnection::RollbackTrans()
{
ASSERT(m_pConnection != NULL);
try
{
return SUCCEEDED(m_pConnection->RollbackTrans());
}
catch (_com_error e)
{
TRACE(_T(":( RollbackTrans发生错误: %s\n"), e.ErrorMessage());
return FALSE;
}
return FALSE;
}
/*########################################################################
------------------------------------------------
CAdoRecordSet class 构造函数
------------------------------------------------
########################################################################*/
CAdoRecordSet::CAdoRecordSet()
{
m_pRecordset = NULL;
m_pConnection = NULL;
}
CAdoRecordSet::CAdoRecordSet(CAdoConnection *pConnection)
{
m_pConnection = pConnection;
}
CAdoRecordSet::~CAdoRecordSet()
{
Close();
}
/*========================================================================
Params:
- strSQL: 计算 Command 对象的变量名,SQL 语句,表名,存储过程调
用或持久 Recordset 文件名.
- CursorType: 可选.CursorTypeEnum 值, 确定打开Recordset时应
该使用的游标类型.可为下列常量之一.
常量 说明
-----------------------------------------------
adOpenForwardOnly 打开仅向前类型游标.
adOpenKeyset 打开键集类型游标.
adOpenDynamic 打开动态类型游标.
adOpenStatic 打开静态类型游标.
-----------------------------------------------
- LockType: 可选,确定打开Recordset时应该使用的锁定类型(并发)的
LockTypeEnum值,可为下列常量之一.
常量 说明
-----------------------------------------------
adLockReadOnly 只读 — 不能改变数据.
adLockPessimistic 保守式锁定 - 通常通过在编辑时立即锁定数据源的记录.
adLockOptimistic 开放式锁定 - 只在调用 Update 方法时才锁定记录.
adLockBatchOptimistic 开放式批更新 - 用于批更新模式(与立即更新模式
相对).
-----------------------------------------------
- lOption 可选. 长整型值, 用于指示 strSQL 参数的类型可为下列
常量之一.
常量 说明
-------------------------------------------------
adCmdText 指示strSQL为命令文本, 即普通的SQL语句.
adCmdTable 指示ADO生成SQL查询以便从在strSQL中命名的表中返
回所有行.
adCmdTableDirect 指示所作的更改在strSQL中命名的表中返回所有行.
adCmdStoredProc 指示strSQL为存储过程.
adCmdUnknown 指示strSQL参数中的命令类型为未知.
adCmdFile 指示应从在strSQL中命名的文件中恢复保留(保存的)
Recordset.
adAsyncExecute 指示应异步执行strSQL.
adAsyncFetch 指示在提取 Initial Fetch Size 属性中指定的初始
数量后,应该异步提取所有剩余的行.如果所需的行尚未提
取,主要的线程将被堵塞直到行重新可用.
adAsyncFetchNonBlocking 指示主要线程在提取期间从未堵塞. 如果所请求
的行尚未提取,当前行自动移到文件末尾.
==========================================================================*/
HRESULT CAdoRecordSet::Open(LPCTSTR strSQL, long lOption, CursorTypeEnum CursorType, LockTypeEnum LockType)
{
try
{
if (m_pConnection == NULL)
{
return -1;
}
else if (m_pRecordset == NULL)
{
m_pRecordset.CreateInstance("ADODB.Recordset");
}
m_pRecordset->Open(_bstr_t(strSQL), _variant_t((IDispatch*)m_pConnection->GetConnection(), true),
CursorType, LockType, lOption);
if (m_pRecordset == NULL)
{
return -1;
}
return (m_pRecordset->adoEOF) ? 0 : 1;
}
catch (_com_error e)
{
TRACE(_T(":( 打开记录集发生错误: %s\n"), e.ErrorMessage());
return -1;
}
}
/*===================================================================
Name: 关闭打开的对象及任何相关对象.
-----------------------------------------------------
Remarks: 使用Close方法可关闭Recordset对象以便释放所有关联的系统资源.
关闭对象并非将它从内存中删除, 可以更改它的属性设置并且在此后再次打
开.要将对象从内存中完全删除, 可将对象变量设置为 Nothing.
使用Close方法关闭Recordset对象的同时, 将释放关联的数据和可能已
经通过该特定Recordset对象对数据进行的独立访问.随后可调用Open方法重
新打开具有相同属性或已修改属性的Recordset.在Recordset对象关闭后,调
用任何需要活动游标的方法将产生错误.
如果正在立即更新模式下进行编辑,调用Close方法将产生错误, 应首先
调用Update或CancelUpdat 方法.如果在批更新期间关闭Recordset对象, 则
自上次UpdateBatch调用以来所做的修改将全部丢失.
如果使用Clone方法创建已打开的Recordset对象的副本,关闭原始Recordset
或其副本将不影响任何其他副本.
=====================================================================*/
BOOL CAdoRecordSet::Close()
{
try
{
if (m_pRecordset != NULL && m_pRecordset->State != adStateClosed)
{
return SUCCEEDED(m_pRecordset->Close());
}
}
catch (const _com_error& e)
{
TRACE(_T(":( 关闭记录集发生错误: %s\n"), e.ErrorMessage());
return FALSE;
}
return TRUE;
}
/*########################################################################
------------------------------------------------
记录集更新操作
------------------------------------------------
########################################################################*/
/*===================================================================
Remarks: 添加新的纪录.先AddNew()声明, 然后用PutCollect()设置每
列的值, 最后用Update()更新数据库.
=====================================================================*/
BOOL CAdoRecordSet::AddNew()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->AddNew());
}
}
catch (_com_error e)
{
TRACE(_T(":( AddNew发生错误: %s\n"), e.ErrorMessage());
return FALSE;
}
return FALSE;
}
/*===================================================================
Remarks: 在调用AddNew()等方法后,调用此方法完成更新或修改.
=====================================================================*/
BOOL CAdoRecordSet::Update()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->Update());
}
}
catch (_com_error e)
{
TRACE(_T(":( Update发生错误: %s\n"), e.ErrorMessage());
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 取消在调用 Update 方法前对当前记录或新记录所作的任何更改.
-----------------------------------------------------
Remarks: 使用 CancelUpdate 方法可取消对当前记录所作的任何更改或
放弃新添加的记录.在调用 Update 方法后将无法撤消对当前记录或新记录
所做的更改,除非更改是可以用 RollbackTrans 方法回卷的事务的一部分,
或者是可以用 CancelBatch 方法取消的批更新的一部分.
如果在调用 CancelUpdate 方法时添加新记录,则调用 AddNew 之前的当前
记录将再次成为当前记录.
如果尚未更改当前记录或添加新记录,调用 CancelUpdate 方法将产生错误.
==========================================================================*/
BOOL CAdoRecordSet::CancelUpdate()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->CancelUpdate());
}
}
catch (_com_error e)
{
TRACE(_T(":( CancelUpdate发生错误: %s\n"), e.ErrorMessage());
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 取消挂起的批更新.
-----------------------------------------------------
Params: AffectRecords 可选的 AffectEnum 值,决定CancelBatch
方法所影响记录的数目,可为下列常量之一:
常量 说明
-------------------------------------------------
AdAffectCurrent 仅取消当前记录的挂起更新.
AdAffectGroup 对满足当前 Filter 属性设置的记录取消挂起更新.
使用该选项时,必须将 Filter 属性设置为合法的预
定义常量之一.
AdAffectAll 默认值.取消 Recordset 对象中所有记录的挂起更
新,包括由当前 Filter 属性设置所隐藏的任何记录.
==========================================================================*/
BOOL CAdoRecordSet::CancelBatch(AffectEnum AffectRecords)
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->CancelBatch(AffectRecords));
}
}
catch(_com_error e)
{
TRACE(_T(":( CancelBatch发生错误: %s\n"), e.ErrorMessage());
return FALSE;
}
return FALSE;
}
/*========================================================================
Params: AffectRecords: AffectEnum值, 确定Delete方法所影响的记录数
目,该值可以是下列常量之一.
常量 说明
-------------------------------------------------
AdAffectCurrent 默认.仅删除当前记录.
AdAffectGroup 删除满足当前Filter属性设置的记录.要使用该选项,
必须将 Filter 属性设置为有效的预定义常量之一.
adAffectAll 删除所有记录.
adAffectAllChapters 删除所有子集记录.
==========================================================================*/
BOOL CAdoRecordSet::Delete(AffectEnum AffectRecords)
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->Delete(AffectRecords));
}
}
catch(_com_error e)
{
TRACE(_T(":( Delete发生错误: %s\n"), e.ErrorMessage());
return FALSE;
}
return FALSE;
}
/*########################################################################
------------------------------------------------
记录集导航操作
------------------------------------------------
Remarks:
使用MoveFirst方法将当前记录位置移动到Recordse中的第一个记录.
使用MoveLast方法将当前记录位置移动到Recordset中的最后一个记录.
Recordset对象必须支持书签或向后光标移动;否则调用该方法将产生错误.
使用MoveNext方法将当前记录向前移动一个记录(向Recordset的底部).如果
最后一个记录是当前记录并且调用MoveNext方法,则ADO将当前记录设置到
Recordset(EOF为True)的尾记录之后.当EOF属性已经为True时试图向前移动
将产生错误.
使用MovePrevious方法将当前记录位置向后移动一个记录(向记录集的顶部).
Recordset 对象必须支持书签或向后游标移动;否则方法调用将产生错误.
如果首记录是当前记录并且调用MovePrevious方法,则ADO将当前记录设置在
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -