272上位机VC MFC使用ODBC执行事务处理
272上位机VC MFC使用ODBC执行事务处理
功能展示
在很多场合都需要进行事务处理,不然会出现我们不想要的结果,当前例程实现事务处理功能,例程在删除记录时把表Basic设为可删除记录状态,把Course设为不可状态,这样执行删除两表记录时由于删除Course表记录失败而回滚,Basic表中记录也未被删除,效果如图;
要点提示 1.事务处理就是把对数据库一系列的操作都集中到一起执行,如果一个操作不成功,则这一系列的操作都不执行; 2.事务处理一般步骤为: 使用CanTransact()函数查看能否进行事务处理; 使用BeginTransact函数开始事务处理; 使用CommitTransact函数提交事务; 如果失败就捕获错误,用RollBack函数进行事务回滚;
3.注意我们当前例程执行删除操作时是直接执行SQL语句而不是使用m_pSet->Delete(),该函数在某些情况下不能成功回滚事务,因为该函数执行的删除操作不能够被撤销 实现功能 1.新建基于对话框的应用程序; 2.依照例程界面依次添加三静态文本控件ID分别修改为IDC_STATIC_COL1,IDC_STATIC_COL2,IDC_STATIC_COL3,三编辑框控件,ID修改为IDC_EDIT_COL1,IDC_EDIT_COL2,IDC_EDIT_COL3,三按钮控件<打开Course表><打开Basic表><删除记录(测试事务)> 3.在主对话框头文件中添加包含两头文件#include<afxdb.h> #include<ODBCINST.H> 再添加两成员变量public:CRecordset* m_pSet;//记录集对象的指针 CDatabase m_DB;并在构造函数中初始化 m_pSet=NULL;析构函数中消除if(m_pSet!=NULL) delete m_pSet;
4.在OnInitDialog()函数中使用我们例程根目录数据库文件注册数据源 - if(m_pSet==NULL)
- {
- if(!SQLConfigDataSource(NULL, //父窗口指针;
- ODBC_ADD_DSN, //添加的数据源的类型;
- "Microsoft Access Driver (*.mdb)",//驱动程序名;
- "DSN=transaction\0" //数据源名
- "Description=工控编程吧测试用\0" //数据源的说明
- "FileType=Microsoft Access\0" //数据源文件类型
- "DBQ=E:\\每日任务\\Transaction.mdb\0"//数据库文件全路径名
- "MaxScanRows=0\0")
- )
- {
- AfxMessageBox("创建数据源失败!!");
- return FALSE;
- }
复制代码- m_pSet=new CRecordset(&m_DB);
- if(!m_DB.OpenEx(_T("DSN=transaction"),0))
- {
- AfxMessageBox("打开数据源失败!!");
- return FALSE;
- }
- m_pSet->Open(CRecordset::dynaset,_T("Select * from Basic"));
- }
复制代码5.关联前面添加的三个按钮控件函数 - void CGkbc8Dlg::OnOpenCourse()
- {
- CWnd *pWnd1=GetDlgItem(IDC_STATIC_COL1);//得到控件句柄
- CWnd *pWnd2=GetDlgItem(IDC_STATIC_COL2);//
- CWnd *pWnd3=GetDlgItem(IDC_STATIC_COL3);//
- pWnd1->SetWindowText("学号");
- pWnd2->SetWindowText("科目");
- pWnd3->SetWindowText("成绩");
- if(m_pSet->IsOpen())
- {
- m_pSet->Close();
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,"SELECT * FROM Course ORDER BY Col1");
- m_pSet->MoveFirst();
- }
- else
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,"SELECT * FROM Course ORDER BY Col1");
- //<>
- CString string;
- m_pSet->MoveFirst();//从第一个记录开始
- m_pSet->GetFieldValue((short)0,string);
- SetDlgItemText(IDC_EDIT_COL1,string);
- m_pSet->GetFieldValue((short)1,string);
- SetDlgItemText(IDC_EDIT_COL2,string);
- m_pSet->GetFieldValue((short)2,string);
- SetDlgItemText(IDC_EDIT_COL3,string);
- }
- void CGkbc8Dlg::OnOpenBasic()
- {
- CWnd *pWnd1=GetDlgItem(IDC_STATIC_COL1);//得到控件句柄
- CWnd *pWnd2=GetDlgItem(IDC_STATIC_COL2);//
- CWnd *pWnd3=GetDlgItem(IDC_STATIC_COL3);//
- pWnd1->SetWindowText("学号");
- pWnd2->SetWindowText("籍贯");
复制代码- pWnd3->SetWindowText("电话");
- if(m_pSet->IsOpen())
- {
- m_pSet->Close();
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,"SELECT * FROM Basic ORDER BY Col1");
- m_pSet->MoveFirst();
- }
- else
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,"SELECT * FROM Basic ORDER BY Col1");
- //<>
- CString string;
- m_pSet->MoveFirst();//从第一个记录开始
- m_pSet->GetFieldValue((short)0,string);
- SetDlgItemText(IDC_EDIT_COL1,string);
- m_pSet->GetFieldValue((short)1,string);
- SetDlgItemText(IDC_EDIT_COL2,string);
- m_pSet->GetFieldValue((short)2,string);
- SetDlgItemText(IDC_EDIT_COL3,string);
- }
- void CGkbc8Dlg::OnRecordDelete()
- {
- CString sDel;
- //******************测试能否进行事务处理******************
- if(m_pSet->m_pDatabase->CanTransact())
- m_pSet->m_pDatabase->BeginTrans();
- else
- return;
- //*****************删除Basic表中的指定的记录*************
- TRY
- {
- sDel="DELETE FROM Basic WHERE Basic.Col1=2;";//定义SQL语句
- if(m_pSet->IsOpen())//打开Basic表
- {
- m_pSet->Close();
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,"SELECT * FROM Basic ORDER BY Col1");
- m_pSet->MoveFirst();
- }
- else
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,"SELECT * FROM Basic ORDER BY Col1");
- m_pSet->m_pDatabase->ExecuteSQL(sDel);//执行删除操作
- //*****************删除Course表中指定的记录******************
- sDel="DELETE FROM Course WHERE Course.Col1=2;";//定义SQL语句
-
复制代码- if(m_pSet->IsOpen())//打开Course表
- {
- m_pSet->Close();
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,"SELECT * FROM Course ORDER BY Col1",CRecordset::readOnly);
- m_pSet->MoveFirst();
- }
- else
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,"SELECT * FROM Course ORDER BY Col1",CRecordset::readOnly);
- m_pSet->m_pDatabase->ExecuteSQL(sDel);//执行删除操作
- //*********************事务结束提交事务*************
- m_pSet->m_pDatabase->CommitTrans();
- }
- CATCH(CDBException,e)//捕捉错误
- {
- AfxMessageBox("事务处理失败!!");
- m_pSet->m_pDatabase->Rollback();//回滚事务
- }
- END_CATCH
- }
复制代码我们来演示功能实现的整个过程 如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
|